java后端实现微信小程序登录
要实现微信小程序登录,需要进行以下步骤:
在微信公众平台上注册小程序,并获取小程序的AppID和AppSecret。
在小程序中调用wx.login()方法获取用户的code。
将code发送到后端服务器,后端服务器使用AppID和AppSecret向微信服务器发送请求,获取用户的openid和session_key。
将openid和session_key保存到后端服务器的数据库中,并生成一个token返回给小程序。
小程序将token保存到本地,以后每次请求都携带token,后端服务器根据token验证用户身份。
以下是Java后端实现微信小程序登录的示例代码:
@RestController
@RequestMapping("/api")
public class LoginController {
@Autowired
private UserService userService;
@PostMapping("/login")
public Result login(@RequestBody LoginRequest loginRequest) {
String code = loginRequest.getCode();
String appId = "your_app_id";
String appSecret = "your_app_secret";
String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code";
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject(url, String.class);
JSONObject jsonObject = JSON.parseObject(response);
String openid = jsonObject.getString("openid");
String sessionKey = jsonObject.getString("session_key");
User user = userService.getUserByOpenid(openid);
if (user == null) {
user = new User();
user.setOpenid(openid);
userService.addUser(user);
}
String token = JwtUtil.createToken(user.getId());
return Result.success(token);
}
}
在上面的代码中,LoginRequest是一个包含code的请求对象,UserService是一个用户服务类,getUserByOpenid方法用于根据openid获取用户信息,addUser方法用于添加用户信息,JwtUtil是一个用于生成token的工具类。
接下来,我们需要在后端实现token的验证和用户身份的认证。可以使用Spring Security框架来实现。以下是示例代码:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager(), userService))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
在上面的代码中,我们配置了Spring Security的HttpSecurity,允许/api/login接口的匿名访问,其他接口需要进行身份认证。我们还添加了JwtAuthenticationFilter和JwtAuthorizationFilter,用于处理token的验证和用户身份的认证。JwtAuthenticationFilter用于从请求中获取token,并进行验证,JwtAuthorizationFilter用于根据token获取用户信息,并进行身份认证。我们还配置了一个UserDetailsService,用于从数据库中获取用户信息。
最后,我们需要实现JwtAuthenticationFilter和JwtAuthorizationFilter。以下是示例代码:
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationManager authenticationManager;
public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
try {
LoginRequest loginRequest = new ObjectMapper().readValue(request.getInputStream(), LoginRequest.class);
return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getCode(), null));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
String token = JwtUtil.createToken(((User) authResult.getPrincipal()).getId());
response.addHeader("Authorization", "Bearer " + token);
}
}
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {
private UserService userService;
public JwtAuthorizationFilter(AuthenticationManager authenticationManager, UserService userService) {
super(authenticationManager);
this.userService = userService;
}
@Override
protected void doFilterInternal(HttpServletRequest _