苍穹外卖微信登录

小程序登录流程

实现

- 服务端存储
user 的 openId , appId+code 只会返回一个不变的 openId, 即一个用户在一个 appid 小程序上登录只会返回一个确定的 openId , 这个 openId可以唯一表示该用户.
- 后续客户端每次请求都会携带
token
@PostMapping("/login")
public Result<UserLoginVO> login(@RequestBody UserLoginDTO userLoginDTO){
/**
* 获取小程序登录得来的 code
* 后端发送 appid secret code 到微信接口==> 获得session_key openId
* 后端返回前端 openId,token,id
*/
log.info("微信登录:{}",userLoginDTO.getCode());
// user 中有 openId, User user = userService.wxLogin(userLoginDTO);
//创建jwt
Map<String,Object> map = new HashedMap();
map.put(JwtClaimsConstant.USER_ID,user.getId());
String jwt = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), map);
UserLoginVO vo = UserLoginVO.builder()
.id(user.getId())
.openid(user.getOpenid())
.token(jwt)
.build();
return Result.success(vo);
}
public User wxLogin(UserLoginDTO userLoginDTO) {
// 获取openid
String open_id = getOpenId(userLoginDTO.getCode());
/**
* 判断 openid非空,为空表示登录失败
* 不空=>判断是否为新用户(查询用户表) 新->注册->返回user
* 非新->返回user
*/
if (open_id == null) {
throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
}
User user = userMapper.getByOpenId(open_id);
if (user == null) {
user = User.builder()
.openid(open_id)
.createTime(LocalDateTime.now())
.build();
userMapper.insert(user);
}
return user;
}
/**
* 通过 code 获取 openId
* @param code
* @return
*/private String getOpenId(String code){
Map<String, String> map = new HashMap();
map.put("appid", weChatProperties.getAppid());
map.put("secret", weChatProperties.getSecret());
map.put("js_code", code);
map.put("grant_type", "authorization_code");
String json = HttpClientUtil.doGet(WX_LOGIN, map);
JSONObject jsonObject = JSON.parseObject(json);
String open_id = jsonObject.getString("openid");
return open_id;
}