微信小程序登录
1、前端请求
前端调用wx.login()获取临时授权码(凭证)code,然后返回给后端。
2、后端接收、调用
后端接收到前端返回的临时授权码(凭证)code之后,携带code、appid、appsecret访问微信api,微信api返回唯一登录凭证openid等信息。
登录api网址:
获取openid:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html
获取接口调用凭据AccessToken:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getAccessToken.html
3、储存、封装
后端拿到微信api返回的openid等信息,再使用openapi调用获取微信手机号、头像等信息封装到一起,储存到数据库中,以便登录校验,信息更新。
4、响应
后端将可开放数据负载进token,返回给前端。
使用jwt进行封装
// 将用户id存入token,返回
Map<String, Object> claims = new HashMap<>();
claims.put(Constants.JWT_USERID, member.getId());
claims.put(Constants.JWT_USERNAME, member.getName());
String token = JwtUtil.createJWT(jwtProperties.getBSecretKey(), jwtProperties.getTtl(), claims);
5、再请求
前端token过期或者退出登录后再次请求登录时,重复获取openid步骤,然后将获取到的openid与数据库的openid进行对比,没有一致的openid视为新用户注册,有一致的id则进行信息更新操作,然后封装token返回。
public class JwtUtil {
/**
* 生成jwt
* 使用Hs256算法, 私匙使用固定秘钥
*
* @param secretKey jwt秘钥
* @param dateOffset jwt过期时间(小时)
* @param claims 设置的信息
* @return token
*/
public static String createJWT(String secretKey, int dateOffset, Map<String, Object> claims) {
// 指定签名的时候使用的签名算法,也就是header那部分
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
// 设置jwt的body
JwtBuilder builder = Jwts.builder()
// 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
.setClaims(claims)
// 设置签名使用的签名算法和签名使用的秘钥
.signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))
// 设置过期时间
.setExpiration(DateUtil.offset(new Date(), DateField.HOUR_OF_DAY, dateOffset));
return builder.compact();
}
JwtUtils工具类(加密解密token)
/**
* Token解密
*
* @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个
* @param token 加密后的token
* @return claims
*/
public static Claims parseJWT(String secretKey, String token) {
try {
// 得到DefaultJwtParser
Claims claims = Jwts.parser()
// 设置签名的秘钥
.setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))
// 设置需要解析的jwt
.parseClaimsJws(token).getBody();
return claims;
} catch (Exception e) {
throw new RuntimeException("没有权限,请登录");
}
}
}