JWT-RESTful进行身份认证( 二 )


直接调用 该方法
权限控制装饰器
# -*- coding: utf8 -*-from functools import wrapsfrom typing import Optional, List, Tuplefrom flask import current_appfrom titan.user.enum import RoleEnumfrom titan.factory import redisfrom titan.cache import SignOutUserListKeyfrom stardust.exceptions import PermissionDenied, Unauthenticatedfrom stardust.auth import current_authdef _access_control(auth_roles: Optional[List[RoleEnum]] = None) -> Tuple[str, RoleEnum]:id_ = current_auth.iduser_role = RoleEnum(current_auth.role)env = current_auth.envif redis.sismember(SignOutUserListKey, id_):raise PermissionDenied(message='请重新登录')if not auth_roles:auth_roles = [RoleEnum.DEFAULT]if user_role != RoleEnum.ADMIN and user_role not in auth_roles:raise Unauthenticated(message="无权访问")if current_app.config['ENV'] != env:raise Unauthenticated(message="环境有误,请重新登录")return id_, user_roledef auth_control(roles: Optional[List[RoleEnum]] = None):def wrapper(func):@wraps(func)def wrap_func(*args, **kwargs):id_, user_role = _access_control(roles)return func(id_, user_role, *args, **kwargs)return wrap_funcreturn wrapper
@blueprint.route('/summary', methods=['GET'])@auth_control()def task_issue_summary(*args, **kwargs):# 获取请求数据,数据校检data_pb = api_request(issue_pb2.AnnotationIssueSummeryRequestProto)required = {'task_id', 'container_id'}variable_check(data_pb, required)frame_indexes = controller.task_issue_summary(current_auth.id, data_pb.task_id, data_pb.container_id,data_pb.sampling_id)resp_dict = dict(frame_indexes=frame_indexes)return api_response(issue_pb2.AnnotationIssueSummaryResponseProto, resp_dict)
Go语言实现
package mainimport ("fmt""github.com/dgrijalva/jwt-go""github.com/gin-gonic/gin""net/http""time")//自定义一个字符串var jwtkey = []byte("www.topgoer.com")var str stringtype Claims struct {UserId uintjwt.StandardClaims}func main() {r := gin.Default()r.GET("/set", setting)r.GET("/get", getting)//监听端口默认为8080r.Run(":8080")}//颁发tokenfunc setting(ctx *gin.Context) {expireTime := time.Now().Add(7 * 24 * time.Hour)claims := &Claims{UserId: 2,StandardClaims: jwt.StandardClaims{ExpiresAt: expireTime.Unix(), //过期时间IssuedAt:time.Now().Unix(),Issuer:"127.0.0.1",// 签名颁发者Subject:"user token", //签名主题},}fmt.Println(claims)token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)fmt.Println(token)tokenString, err := token.SignedString(jwtkey)fmt.Println(tokenString)if err != nil {fmt.Println(err)}str = tokenStringctx.JSON(200, gin.H{"token": tokenString})}//解析tokenfunc getting(ctx *gin.Context) {tokenString := ctx.GetHeader("Authorization")//vcalidate token formateif tokenString == "" {ctx.JSON(http.StatusUnauthorized, gin.H{"code": 401, "msg": "权限不足"})ctx.Abort()return}token, claims, err := ParseToken(tokenString)if err != nil || !token.Valid {ctx.JSON(http.StatusUnauthorized, gin.H{"code": 401, "msg": "权限不足"})ctx.Abort()return}fmt.Println(111)fmt.Println(claims.UserId)}func ParseToken(tokenString string) (*jwt.Token, *Claims, error) {Claims := &Claims{}token, err := jwt.ParseWithClaims(tokenString, Claims, func(token *jwt.Token) (i interface{}, err error) {return jwtkey, nil})fmt.Println(token, Claims)return token, Claims, err}
获取token
JWT 更新状态问题(白名单)
如何让用户无感知获取最新token
参考
总结 优点
因为json的通用性,所以JWT是可以进行跨语言支持的,像JAVA,,,PHP等很多语言都可以使用 。
因为有了部分,所以JWT可以在自身存储一些其他业务逻辑所必要的非敏感信息 。
便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的 。
它不需要在服务端保存会话信息, 所以它易于应用的扩展