一 什么是微信登录功能
二 实现微信登录功能的整体逻辑
首先,我们来看微信小程序登录的官方流程图:
从上面这个流程图可以看见,微信登录主要分为以下几个步骤:
1.微信小程序通过调用wx.login()方法来获取一个code。
2.微信小程序前端得到这个code后,通过发送请求,把这个code传给我们后端服务器。
3.我们后端服务接收到这个code后,再加上微信小程序校验凭证:appid,secret, grant_type(这三个是通过我们创建的微信小程序生成的), 以及我们得到的js_code一并作为参数,使用HttpCent发送请求给微信接口服务,这样就会给我们返回一个openid,这个openid就是每一个用户登录的唯一标识,我们就是通过这个来判断用户是否登录。
4.根据得到的openid去数据库中查找用户,从而判断用户是否登录,如果没登录,我们在服务端需要做一个添加该用户的sql操作,记住,必须要有这个openid字段。
5.逻辑业务完成之后,我们就可以返回查询到的User对象并且生成一个jwt令牌给微信小程序前端,为什么要给用户生成一个jwt令牌?因为这用户在执行小程序的其他功能时,通过判断用户是否已经登录,有些功能需要登录才能放行。
至此,微信登录功能就已经全部完成!
三 微信登录功能实现步骤
① 在微信小程序端定义好请求路径,同时需要传入参数code(需要学习微信小程序的前端编码技术)
② 在服务端配置好微信小程序的appid和secret(这个是在你创建的微信小程序后生成的)
另外,如果你是要jwt令牌的话,还需要配置微信登陆的jwt令牌。
③ 在controller层接收到前端传来的code,并且调用server层实现相关登录逻辑后,得到一个查询到的用户对象,并且未这个对象生成jwt令牌,返回给微信小程序前端。
@RestController
@Slf4j
@RequestMapping("/user/user")
@Api("C端用户相关接口")
public class UserController {
@Autowired
private UserServer userServer ;
@Autowired
private JwtProperties jwtProperties ;
@PostMapping("/login")
@ApiOperation("微信登录")
public Result<UserLoginVO> login(@RequestBody UserLoginDTO userLoginDTO){
log.info("微信用户登录code:{}" , userLoginDTO.getCode()) ;
// 微信登录
User user = userServer.wxLogin(userLoginDTO) ;
// 为微信用户生成jwt令牌
HashMap<String, Object> claims = new HashMap<>();
claims.put(JwtClaimsConstant.USER_ID, user.getId()) ;
String jwt = JwtUtil.createJWT(jwtProperties.getAdminSecretKey(), jwtProperties.getUserTtl(), claims);
// 封装返回的UserLoginVo
UserLoginVO userLoginVo = UserLoginVO.builder()
.id(user.getId())
.openid(user.getOpenid())
.token(jwt)
.build();
return Result.success(userLoginVo) ;
}
}
@Service
@Slf4j
public class UserServerImpl implements UserServer {
// 定义访问wx接口服务的地址
public static final String wx_login = "https://api.weixin.qq.com/sns/jscode2session" ; //固定的
@Autowired
private WeChatProperties weChatProperties ;
@Autowired
private UserMapper userMapper ;
public User wxLogin(UserLoginDTO userLoginDTO) {
// 1.调用微信接口服务,获取当前用户的openid
HashMap<String, String> map = new HashMap<>();
map.put("appid",weChatProperties.getAppid()); //小程序appid
map.put("secret",weChatProperties.getSecret()); //小程序appSecret
map.put("js_code", userLoginDTO.getCode()) ; //登录微信时获取的code
map.put("grant_type","authorization_code") ; //授权类型:authorization_code(固定的)
String json = HttpClientUtil.doGet(wx_login, map); //返回的是一个json对象
// 把json格式的openid解析出来
JSONObject jsonObject = JSON.parseObject(json);
String openid = jsonObject.getString("openid");
System.out.println("openid="+openid);
// 2.判断openid是否为空,如果为空表示登录失败,抛出异常
if(openid==null){
throw new LoginFailedException(MessageConstant.LOGIN_FAILED) ; //登陆失败
}
// 3.判断当前用户的openid有没有在我们的数据库中,如果没有,则说明是新用户,我们需要存起来
User user = userMapper.getByOpenid(openid);
if (user==null){
System.out.println("该用户为新用户...");
user = User.builder()
.openid(openid)
.createTime(LocalDateTime.now())
.build();
// 保存user对象到数据库
userMapper.insertUser(user);
}
// 4.返回用户对象
return user ;
}
}
至此,整个微信登录功能就实现成功啦!