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 _