小程序获取jwt令牌

  • 生成token
    登录方式有很多种,,用户名密码,email,电话号码,微信登录,,等,,每一种方式会根据传入的用户信息,去校验用户信息,然后生成token,,,
    微信小程序中,,生成token是调用官方接口,,通过前端wx.login()传递的code码,,后端调用微信官方接口,这个接口需要传递三个参数:
    1. 前端传递过来的code吗
    2. 小程序的appid
    3. 小程序的appsecret
      这个连接是 https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code
      ,返回一个map,,这个 map包含了openid ,
      什么是openid: openid是这个小程序对每一个用户的唯一标识,,每一个用户都有不同的openid,,但是如果业务横跨了多个小程序和公众号,,需要使用unionid, , openid只能保证当前这个小程序用户id是唯一的,,

获取到这个openid之后,,在自己的user表中,查找是否有这个openid的用户,,如果有,说明这个用户之前登录过,,如果没有,说明这个用户是第一次授权登录,,,需要将这个用户写入到user表中,,一个静默的登录注册,

登录注册之后,,获取这个user的token,,,因为是带权限的token,,写入的信息,需要有 用户唯一标识uid,,用户权限信息 scope,,token的签发时间,,和token的过期时间,,

接口权限怎么校验:
设置一个注解标明这个接口的权限 比如 @ScopeLevel(5) , 获取当前登录用户的等级数字,,和 接口中的等级数字比较,,,

怎么校验权限:
在拦截器里面拦截这个token,,这个token写在请求头Authentication字段中,并设置前缀Bearer ,拦截器拦截的时候,先判断这个接口是否打有权限注解,,如果没有打注解,,就不需要做权限拦截,,,直接放行,如果打了注解,,就需要解析这个token,,解析完了之后将用户的权限等级,和api注解上的权限等级,做判断,,是否具有权限

jwt使用

java的jwt工具包有很多,auth0 只是其中的一个:

 <dependency>
            <groupId>com.auth0groupId>
            <artifactId>java-jwtartifactId>
            <version>3.8.1version>
        dependency>
  • 生成token

    1. 设置一个jwt的算法,,传入一个盐字段
    2. 写入自己要的 claims
    3. 设置签发时间,和过期时间,生成token字符串,,JWT.create().sign()
  • 解析token

    1. 设置一个jwt算法,传入盐字段
    2. JWT.require().build() 生成解析器
    3. 解析器解析token,返回claims
@Component
public class JwtToken {


    private static String jwtKey;

    private static Integer expiredTimeIn;

    // 默认 8
    private static Integer scopeLevel = 8;

    @Value("${missyou.security.jwt-key}")
    public  void setJwtKey(String jwtKey) {
        JwtToken.jwtKey = jwtKey;
    }

    @Value("${missyou.security.token-expired-in}")
    public  void setExpiredTimeIn(Integer expiredTimeIn) {
        JwtToken.expiredTimeIn = expiredTimeIn;
    }


    public static boolean verify(String token){
        try {
            Algorithm algorithm = Algorithm.HMAC256(JwtToken.jwtKey);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT decodedJWT = verifier.verify(token);
            return true;
        } catch (IllegalArgumentException e) {
            throw new RuntimeException(e);
        } catch (JWTVerificationException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 解析token  获取claims
     * @param token
     */
    public static Optional<Map<String, Claim>> getClaims(String token){
        Algorithm algorithm = Algorithm.HMAC256(JwtToken.jwtKey);
        // 校验器
        JWTVerifier jwtVerifier = JWT.require(algorithm).build();
        DecodedJWT decodedJWT  = null;
        try {
             decodedJWT = jwtVerifier.verify(token);
        } catch (JWTVerificationException e) {
            return Optional.empty();
        }


        return Optional.of(decodedJWT.getClaims());

    }




    /**
     * 生成token  ,,,
     * @param uid    uid
     * @param scope  权限分级的数字:  跟api的scope比较
     * @return
     */
    public static String makeToken(Long uid,Integer scope){
        return getToken(uid, scope);
    }

    /**
     * 使用默认的 scope
     */
    public static String makeToken(Long uid){
        return getToken(uid, scopeLevel);
    }


    private static String getToken(Long uid,Integer scope){
        // 加密算法。。   传入盐
        Algorithm algorithm = Algorithm.HMAC256(JwtToken.jwtKey);

        /**
         * jwt 标准数据  既有  签发时间 和 令牌过期时间
         */
        HashMap<String, Date> map = calculateExpiredIssues();
        // 创建jwt      当前令牌签发时间  和  令牌过期时间
        String token = JWT.create().withClaim("uid", uid).withClaim("scope", scope)
                .withExpiresAt(map.get("expiredTime"))  // 过期时间
                .withIssuedAt(map.get("now"))   // 签发时间
                .sign(algorithm);

        return token;
    }


    private static  HashMap<String, Date>  calculateExpiredIssues(){
        HashMap<String, Date> map = new HashMap<>();
        Calendar calendar = Calendar.getInstance();
        Date now = calendar.getTime();
        calendar.add(Calendar.SECOND,JwtToken.expiredTimeIn);
        Date expiredTime = calendar.getTime();
        map.put("now",now);
        map.put("expiredTime",expiredTime);
        return map;
    }
}


你可能感兴趣的:(小程序)