requests实现微博手机验证码自动登录
时间: 2024-06-14 14:07:38 浏览: 8
以下是使用requests实现微博手机验证码自动登录的示例代码:
```python
import requests
# 构造请求头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Referer': 'https://passport.weibo.cn/signin/login',
}
# 构造请求参数
data = {
'username': 'your_username',
'password': 'your_password',
}
# 发送登录请求
response = requests.post('https://passport.weibo.cn/sso/login', headers=headers, data=data)
# 获取登录后的cookie
cookie = response.cookies.get_dict()
# 使用cookie进行后续操作
# ...
```
请注意,上述代码中的`your_username`和`your_password`需要替换为你的微博账号和密码。
相关问题
springsecurity实现手机验证码登录
Spring Security可以很方便地实现手机验证码登录,步骤如下:
1. 添加spring-security-web和spring-security-config依赖。
```xml
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring-security.version}</version>
</dependency>
```
2. 创建一个实现UserDetailsService接口的类,该类用于根据不同的用户名加载用户信息。
```java
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userMapper.selectByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("用户名不存在");
}
return new UserPrincipal(user);
}
}
```
3. 创建一个实现AuthenticationProvider接口的类,该类用于验证用户的手机号和验证码是否正确。
```java
@Service
public class SmsCodeAuthenticationProvider implements AuthenticationProvider {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
SmsCodeAuthenticationToken authenticationToken = (SmsCodeAuthenticationToken) authentication;
String mobile = authenticationToken.getPrincipal().toString();
String code = authenticationToken.getCredentials().toString();
String redisCode = redisTemplate.opsForValue().get(SmsCodeAuthenticationFilter.REDIS_SMS_CODE_KEY_PREFIX + mobile);
if (StringUtils.isBlank(redisCode)) {
throw new BadCredentialsException("验证码不存在或已过期");
}
if (!StringUtils.equals(code, redisCode)) {
throw new BadCredentialsException("验证码不正确");
}
UserDetails userDetails = new UserPrincipal(new User(mobile, "", Collections.emptyList()));
return new SmsCodeAuthenticationToken(userDetails, userDetails.getAuthorities());
}
@Override
public boolean supports(Class<?> authentication) {
return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);
}
}
```
4. 创建一个实现AuthenticationFilter接口的类,该类用于处理短信验证码登录请求。
```java
public class SmsCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public static final String SPRING_SECURITY_FORM_MOBILE_KEY = "mobile";
public static final String SPRING_SECURITY_FORM_CODE_KEY = "code";
public static final String REDIS_SMS_CODE_KEY_PREFIX = "SMS_CODE_";
private String mobileParameter = SPRING_SECURITY_FORM_MOBILE_KEY;
private String codeParameter = SPRING_SECURITY_FORM_CODE_KEY;
private boolean postOnly = true;
public SmsCodeAuthenticationFilter() {
super(new AntPathRequestMatcher("/login/mobile", "POST"));
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("不支持的请求方式: " + request.getMethod());
}
String mobile = obtainMobile(request);
String code = obtainCode(request);
if (StringUtils.isBlank(mobile)) {
throw new UsernameNotFoundException("手机号不能为空");
}
if (StringUtils.isBlank(code)) {
throw new BadCredentialsException("验证码不能为空");
}
SmsCodeAuthenticationToken authRequest = new SmsCodeAuthenticationToken(mobile, code);
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
protected String obtainMobile(HttpServletRequest request) {
return request.getParameter(mobileParameter);
}
protected String obtainCode(HttpServletRequest request) {
return request.getParameter(codeParameter);
}
protected void setDetails(HttpServletRequest request, SmsCodeAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
public void setMobileParameter(String mobileParameter) {
this.mobileParameter = mobileParameter;
}
public void setCodeParameter(String codeParameter) {
this.codeParameter = codeParameter;
}
public void setPostOnly(boolean postOnly) {
this.postOnly = postOnly;
}
public final String getMobileParameter() {
return mobileParameter;
}
public final String getCodeParameter() {
return codeParameter;
}
}
```
5. 在WebSecurityConfigurerAdapter的子类中进行配置。
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private SmsCodeAuthenticationProvider smsCodeAuthenticationProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login/mobile").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").defaultSuccessURL("/home").permitAll()
.and()
.logout().logoutUrl("/logout").permitAll()
.and()
.addFilterBefore(smsCodeAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.csrf().disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(smsCodeAuthenticationProvider)
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SmsCodeAuthenticationFilter smsCodeAuthenticationFilter() {
SmsCodeAuthenticationFilter filter = new SmsCodeAuthenticationFilter();
filter.setAuthenticationManager(authenticationManager());
filter.setAuthenticationSuccessHandler((request, response, authentication) -> {
response.setContentType("application/json;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\": 0, \"message\": \"登录成功\"}");
out.flush();
out.close();
});
filter.setAuthenticationFailureHandler((request, response, exception) -> {
response.setContentType("application/json;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\": 1, \"message\": \"" + exception.getMessage() + "\"}");
out.flush();
out.close();
});
return filter;
}
}
```
6. 在前端页面中添加短信验证码登录的表单。
```html
<form action="/login/mobile" method="post">
<div>
<label>手机号:</label>
<input type="text" name="mobile" />
</div>
<div>
<label>验证码:</label>
<input type="text" name="code" />
<button type="button" onclick="sendSmsCode()">发送验证码</button>
</div>
<div>
<button type="submit">登录</button>
</div>
</form>
```
7. 在后端控制器中添加发送短信验证码的接口。
```java
@RestController
public class SmsCodeController {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@GetMapping("/sms/code")
public void sendSmsCode(String mobile) {
String code = RandomStringUtils.randomNumeric(6);
redisTemplate.opsForValue().set(SmsCodeAuthenticationFilter.REDIS_SMS_CODE_KEY_PREFIX + mobile, code, 5, TimeUnit.MINUTES);
// 发送短信验证码
}
}
```
以上就是使用Spring Security实现手机验证码登录的全部步骤。
springsecurity 实现手机验证码登录完整流程
Spring Security 实现手机验证码登录的完整流程如下:
1. 添加相关依赖
首先,需要在项目中添加 Spring Security 和 Spring Boot Starter Web 的依赖。
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
```
2. 配置 Spring Security
在 Spring Security 的配置类中,需要进行以下配置:
- 配置忽略静态资源
- 配置登录页面和登录处理接口
- 配置登录成功后的跳转页面
- 配置用户认证和授权方式
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Autowired
private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login", "/login/sendCode").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login/authenticate")
.successHandler(customAuthenticationSuccessHandler)
.permitAll()
.and()
.logout()
.permitAll()
.and()
.csrf()
.disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService);
}
}
```
3. 自定义用户认证和授权
需要实现 `UserDetailsService` 接口,根据手机号码查询用户信息,然后实现 `UserDetails` 接口返回用户信息。
```java
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String mobile) throws UsernameNotFoundException {
User user = userRepository.findByMobile(mobile);
if (user == null) {
throw new UsernameNotFoundException("用户不存在");
}
return new CustomUserDetails(user);
}
}
```
实现 `UserDetails` 接口,返回用户信息。
```java
public class CustomUserDetails implements UserDetails {
private User user;
public CustomUserDetails(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.emptyList();
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getMobile();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
```
4. 实现发送验证码和校验验证码
在登录页面中,需要添加一个发送验证码的按钮,点击后通过 Ajax 请求发送验证码到用户手机上。
```javascript
function sendCode() {
$.ajax({
type: 'post',
url: '/login/sendCode',
data: {mobile: $('#mobile').val()},
success: function(result) {
if (result.code === 0) {
alert('验证码发送成功');
} else {
alert(result.message);
}
},
error: function() {
alert('系统错误');
}
});
}
```
服务端接收到请求后,生成一个 6 位数的随机数作为验证码,并保存到 Redis 中,设置过期时间为 5 分钟。
```java
public class SmsCodeSender {
private static final String SMS_CODE_PREFIX = "sms_code_";
public void send(String mobile) {
String code = RandomStringUtils.randomNumeric(6);
System.out.println("给手机号 " + mobile + " 发送验证码 " + code);
RedisUtils.set(SMS_CODE_PREFIX + mobile, code, 5, TimeUnit.MINUTES);
}
}
```
在登录处理接口中,需要校验用户输入的验证码是否与 Redis 中保存的验证码一致。
```java
@Controller
public class LoginController {
@Autowired
private SmsCodeSender smsCodeSender;
@PostMapping("/login/sendCode")
@ResponseBody
public Result sendCode(String mobile) {
smsCodeSender.send(mobile);
return Result.success();
}
@PostMapping("/login/authenticate")
public String login(String mobile, String code, HttpServletRequest request) {
String smsCode = RedisUtils.get(SmsCodeSender.SMS_CODE_PREFIX + mobile);
if (StringUtils.isBlank(smsCode)) {
throw new BadCredentialsException("验证码已过期,请重新发送");
}
if (!smsCode.equals(code)) {
throw new BadCredentialsException("验证码不正确");
}
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(mobile, null);
Authentication authentication = AuthenticationManagerBuilderUtils.getAuthenticationManager().authenticate(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
return "redirect:/index";
}
@GetMapping("/login")
public String loginPage() {
return "login";
}
}
```
5. 自定义登录成功处理器
在登录成功后,需要跳转到指定页面并显示用户信息。
```java
@Component
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.sendRedirect("/index");
}
}
```
6. 完成
至此,Spring Security 实现手机验证码登录的完整流程就完成了。
相关推荐
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)