精华内容
下载资源
问答
  • 关于token和refresh token

    千次阅读 2018-08-21 15:15:17
    0x01. refresh token 的意义 传统的认证方式一般采用cookie/session来实现,这是我们的出发点。 1.为什么选用token而不选用cookie/...而cookie本身不包含用户信息,它指向的是服务器上用户的 session,而由sessi...

    0x01. refresh token 的意义

    传统的认证方式一般采用cookie/session来实现,这是我们的出发点。

    1.为什么选用token而不选用cookie/session?
    本质上token和cookie/session都是字符串,然而token是自带加密算法和用户信息(比如用户id),;而cookie本身不包含用户信息,它指向的是服务器上用户的 session,而由session保存用户信息。这点差别,决定token可以很容易的跨服务器,只要不同服务器实现相同解密算法即可;而cookie/session是存在于某一台服务器上,

    要实现跨服务器比较困难,这是任何基于cookie/session应用天生的短板。

    2.token需要过期时间吗?
    token即是获取受保护资源的凭证,当然必须有过期时间。否则一次登录便可永久使用,认证功能就失去了其意义。非但必须有个过期时间,而且过期时间还不能太长,

    参考各个主流网站的token过期时间,一般不超过1h.

    3.token过期该怎么办?
    token过期,就要重新获取。那么重新获取有两种方式,一是重复第一次获取token的过程(比如登录,扫描授权等),这样做的缺点是用户体验不好,每一小时强制登录一次几乎是无法忍受的。那么还剩第二种方法,那就是主动去刷新token. 主动刷新token的凭证是refresh token,也是加密字符串,并且和token是相关联的。相比获取各种资源的token,refresh token的作用仅仅是获取新的token,因此其作用和安全性要求都大为降低,所以其过期时间也可以设置得长一些。

    4.refresh token需要过期时间么?
    客户端需要保存token和refresh token,以便下一次访问能继续。如果客户端是浏览器,那么两个token都需要设置过期时间;但是可以设置得长一点,可以以天为单位(例如7天、15天);如果客户端是一个服务器,那么refresh token可以永久有效,直到下一次登录,refresh token本身被更新为止。

    以上几个问题是层层递进的,虽说如此,也无法从逻辑上/理论上保证认证系统的绝对安全。但是,我觉得任何一种认证方式,都不能做到逻辑上的绝对安全和毫无漏洞。但是如果给攻击者造成了足够的麻烦,使其破解成本大大提升,那么我们就认为认证系统足够安全了。认证功能最后的落地实现,总是和现实想妥协的结果。

    0x02.  refresh token 刷新机制

     access token 是客户端访问资源服务器的令牌。拥有这个令牌代表着得到用户的授权。然而,这个授权应该是临时的,有一定有效期。这是因为,access token 在使用的过程中可能会泄露。给 access token 限定一个较短的有效期可以降低因 access token 泄露而带来的风险。

      然而引入了有效期之后,客户端使用起来就不那么方便了。每当 access token 过期,客户端就必须重新向用户索要授权。这样用户可能每隔几天,甚至每天都需要进行授权操作。这是一件非常影响用户体验的事情。希望有一种方法,可以避免这种情况。

      于是 Oauth2.0 引入了 refresh token 机制。refresh token 的作用是用来刷新 access token。鉴权服务器提供一个刷新接口,例如:

      http://xxx.xxx.com/refresh?refreshtoken=&client_id=

      传入 refresh token 和 client_id,鉴权服务器验证通过后,返回一个新的 access token。为了安全,Oauth2.0 引入了两个措施:

      1,Oauth2.0 要求,refresh token 一定是保存在客户端的服务器上的,而绝不能存放在狭义的客户端(例如移动 app、PC端软件) 上。调用 refresh 接口的时候,一定是从服务器到服务器的访问;

      2,Oauth2.0 引入了 client_secret 机制。即每一个 client_id 都对应一个 client_secret。这个 client_secret 会在客户端申请 client_id 时,随 client_id 一起分配给客户端。客户端必须把 client_secret 妥善保管在服务器上,决不能泄露。刷新 access token 时,需要验证这个 client_secret。

      于是,实际上的刷新接口应该是类似这样的:

      http://xxx.xxx.com/refresh?refreshtoken=&client_id=&client_secret=

      以上就是 refresh token 机制。refresh token 的有效期非常长,会在用户授权时,随 access token 一起重定向到回调 url,传递给客户端。

     

    0x03. Token refresh的实现

    实现原理:

    在access_token里加入refresh_token标识,给access_token设置短时间的期限(例如一天),给refresh_token设置长时间的期限(例如七天)。当活动用户(拥有access_token)发起request时,在权限验证里,对于requeset的header包含的access_token、refresh_token分别进行验证:

    1、access_token没过期,即通过权限验证;

    2、access_token过期,refresh_token没过期,则返回权限验证失败,并在返回的response的header中加入标识状态的key,在request方法的catch中通过webException来获取标识的key,获取新的token(包含新的access_token和refresh_token),再次发起请求,并返回给客户端请求结果以及新的token,再在客户端更新公共静态token模型;

    3、access_token过期,refresh_token过期即权限验证失败。

     

    下面展示一下关键代码:

    一、登录生成token的时候加入refresh标识

    复制代码
     public TOKEN GetToken(string username, string password)
            {
                TOKEN token = new TOKEN();
                U_USER model = new BLLU_USER().Token(username, password);
                if (model != null)
                {
                    string pwd = new SDDMD().MD5_jie(model.USERPWD);
                    string md5 = new SDDMD().MD5_jia(model.USERID +"&"+ DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") +"&"+ pwd+"&refresh"+ DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    token.access_token = md5;
                    token.token_type = "Authorization";
                    token.expires_in = DateTime.Now.ToString("yyyyMMddHHmmss");
                    //token.refresh_token = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "&refresh";
                }
                return token;
            }
    复制代码
    二、在权限验证环节,对于access_token、refresh_token设置不同时间的期限。再根据判断结果返回状态。

    复制代码
            /// <summary>
            /// 校验token是否有效
            /// </summary>
            /// <param name="encryptTicket">用户提交的Token值</param>
            /// <returns></returns>
            private int ValidateTicket(string encryptTicket)
            {
                try
                {
                    var strTicket = new DBUtility.SDDMD().MD5_jie(encryptTicket);
                    string[] TicketMsg = strTicket.Split('&');
                    if (TicketMsg.Length == 4)
                    {
                        string username = TicketMsg[0];//用户名
                        string passwrod = TicketMsg[2];//密码
                        U_USER model = new BLL.BLLU_USER().Token(username, passwrod);//登陆验证
                        if (model != null)
                        {
                            _userModel = model;
                            //定义Access_Token有效期为1天,精确到秒
                            DateTime dt = Convert.ToDateTime(TicketMsg[1]).AddDays(1);
                            //定义Refresh_Token有效期为1天,精确到秒
                            DateTime dtNew= Convert.ToDateTime(TicketMsg[3].Substring(7)).AddDays(7);//
                            if (dt > DateTime.Now)
                                return 1; //1:access_token没过期
                            else
                            {
                                if (dtNew > DateTime.Now)
                                    return 2; //2:access_token过期,refresh_token没过期
                                else
                                    return 3; //3:access_token过期,refresh_token过期
                            } 
                        }
                        else
                            return 3;
                    }
                    else
                        return 3;
                }
                catch { return 3; }
            }
    复制代码
    三、根据反馈的状态执行不同的方法,“2”(access_token过期,refresh_token没过期)状态下,给返回失败的response的header中加入识别的key值。

    复制代码
            /// <summary>
            /// 定义Access_token验证过期但Reflesh_token有效返回请求刷新token的信息
            /// </summary>
            /// <param name="actionContext"></param>
            protected void RefreshToken(HttpActionContext actionContext)
            {
                var content = "refreshtoken";
                base.HandleUnauthorizedRequest(actionContext);
                var response = actionContext.Response;
                response.StatusCode = HttpStatusCode.Forbidden;
                response.Content = new StringContent(content, Encoding.UTF8, "application/json");
                response.Headers.Add("token", "refresh");//加入识别的key值
            }
    复制代码
    四、request方法中通过Catch捕获webException对象获取Key值,并获取新的token(包含新的access_token和refresh_token),再次发起请求,并返回给客户端请求结果以及新的token。

    复制代码
            /// <summary>
            /// Get head中携带token发送请求
            /// </summary>
            /// <param name="url">WebAPI访问路径</param>
            /// <param name="tokentype">token验证方式 《Authorization》</param>
            /// <param name="tokenvalue">token 《"Bearer " + Token》</param>
            /// <returns></returns>
            public string GetRequest(string url, string tokentype, string tokenvalue)
            {
                try
                {
                    string responseStr = string.Empty;
                    WebRequest request = WebRequest.Create(http + url);
                    request.Timeout = 60000;
                    request.Method = "Get";
                    request.Headers.Add(tokentype, tokenvalue);
                    var response = request.GetResponse();
                    Stream ReceiveStream = response.GetResponseStream();
                    using (StreamReader stream = new StreamReader(ReceiveStream, Encoding.UTF8))
                    {
                        responseStr = stream.ReadToEnd();
                    }
                    return responseStr;
                }
                catch (WebException e)
                {
                    using (WebResponse response = e.Response)
                    {
                        string result=response.Headers.Get("token");//获取识别的KEY
                        if (result == "refresh")//验证是否为状态“2”方法所加的key值
                        {
                            var strTicket = new SDDMD().MD5_jie(tokenvalue.Substring(6));
                            string[] TicketMsg = strTicket.Split('&');
                            string username = TicketMsg[0];//用户名
                            string passwrod = TicketMsg[2];//密码
                            string responseStr = GetRequest("CYUMS/Token/" + username + "/" + passwrod);//获取新的token
                            TOKEN tokenmodel = JsonConvert.DeserializeObject<TOKEN>(responseStr);
                            string secondResponseStr= GetRequest(url, tokenmodel.token_type, "Haval " + tokenmodel.access_token);//再次发起请求
                            return secondResponseStr + "|" + responseStr;//返回请求结果以及新的token
                        }
                        else
                            throw e;
                    }
                }
            }
    复制代码
    五、客户端识别token是否更新,如果更新,就更新公共静态token模型中的access_token的值;

    复制代码
                string user = new HttpHelper().GetRequest(getUserModel, tokenmodel.token_type, "Haval " + tokenmodel.access_token);
                string[] str = user.Split('|');
                if (str.Length == 2)//判断是否有token更新
                {
                    TOKEN tokens = JsonConvert.DeserializeObject<TOKEN>(str[1]);
                    tokenmodel.access_token = tokens.access_token;
                }
                U_USER users = JsonConvert.DeserializeObject<U_USER>(str[0]);
                //business code...

     

    参考文献:

    https://www.cnblogs.com/eedc/p/9088421.html

    https://www.cnblogs.com/blowing00/p/4524132.html

    http://www.cnblogs.com/minirice/p/9232355.html

     

     

    展开全文
  • 它里面包含哪些信息呢?答案是:  哪个用户 在什么时候 授权给哪个客户端 去做什么事情  对于 Oauth2.0 不了解的读者,请看我的另一篇文章:简单介绍 Oauth2.0 原理  这个授权是临时的,有一定有效期。...

      access token 是在 Oauth2.0 协议中,客户端访问资源服务器的令牌(其实就是一段全局唯一的随机字符串)。拥有这个令牌代表着得到用户的授权。它里面包含哪些信息呢?答案是:

     

      哪个用户  在什么时候  授权给哪个客户端  去做什么事情

     

      对于 Oauth2.0 不了解的读者,请看我的另一篇文章:简单介绍 Oauth2.0 原理

     

      这个授权是临时的,有一定有效期。这是因为,access token 在使用的过程中可能会泄露。给 access token 限定一个较短的有效期可以降低因 access token 泄露而带来的风险。

      然而引入了有效期之后,客户端使用起来就不那么方便了。每当 access token 过期,客户端就必须重新向用户索要授权。这样用户可能每隔几天,甚至每天都需要进行授权操作。这是一件非常影响用户体验的事情。希望有一种方法,可以避免这种情况。

      于是 Oauth2.0 引入了 refresh token 机制。refresh token 的作用是用来刷新 access token。鉴权服务器提供一个刷新接口,例如:

     

      POST /refresh

       参数: refreshtoken

       返回:新的 access token

     

      传入 refresh token,鉴权服务器验证通过后,返回一个新的 access token。为了安全,Oauth2.0 引入了两个措施:

      1,Oauth2.0 要求,refresh token 一定是保存在服务器上(应用方的服务器)的,而绝不能存放在狭义的客户端(例如移动 app、PC端软件、浏览器) 上。调用 refresh 接口的时候,一定是从服务器到服务器的访问;

      2,Oauth2.0 引入了 client_id 、client_secret 机制。即每一个应用都会被分配到一个 client_id 和一个对应的 client_secret。应用必须把 client_secret 妥善保管在服务器上,决不能泄露。刷新 access token 时,需要验证这个 client_secret。

      于是,实际上的刷新接口应该是类似这样的:

     

      POST /refresh

       参数:

        refresh token

        client_id

        signatrue 签名,由 sha256(client_id + refresh_token + client_secret) 得到

       返回:新的 access token

     

      以上就是 refresh token 机制。refresh token 的有效期非常长,会在用户授权时,随 access token 一起重定向到回调 url,传递给应用。

     

    转自:https://www.cnblogs.com/blowing00/p/4524132.html

    展开全文
  • 一、什么是JWT(what)JWT(JSON Web Token)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,以JSON对象的形式在各方之间安全地传输信息。JWT是一个数字签名,生成的信息是可以验证并被信任的。使用密钥...

    fb6726c9bf5108ab004b00948a62340a.png

    一、什么是JWT(what)

    • JWT(JSON Web Token)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,以JSON对象的形式在各方之间安全地传输信息。
    • JWT是一个数字签名,生成的信息是可以验证并被信任的。
    • 使用密钥(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对JWT进行签名。
    • JWT是目前最流行的跨域认证解决方案

    1.1 JWT令牌结构

    SON Web令牌以紧凑的形式由三部分组成,这些部分由点(.)分隔,分别是:

    • Header
    • Payload
    • Signature

    即为: xxxx.yyyy.zzzz

    1.1.1 Header

    Header通常由两部分组成:令牌的类型(即JWT)和所使用的签名算法(例如HMAC SHA256或RSA)。 例如:

    {
        "alg": "HS256",
        "typ": "JWT"
    }

    Header会被Base64Url编码为JWT的第一部分。即为:

    $ echo  -n '{"alg":"HS256","typ":"JWT"}'|base64
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

    1.1.2 Payload

    Payload是有关实体(通常是用户)和其他数据的声明,它包含三部分:

    (1)注册声明

    这些是一组预定义的权利要求,不是强制性的,而是建议使用的,以提供一组有用的可互操作的权利要求。其中一些是: iss(JWT的签发者), exp(expires,到期时间), sub(主题), aud(JWT接收者),iat(issued at,签发时间)等。

    注意:声明名称都是三个字符

    (2)公开声明

    公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密。

    (3)私有声明

    私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。

    例子:

    { "iat": 1593955943, 
      "exp": 1593955973, 
      "uid": 10, 
      "username": "test", 
      "scopes": [ "admin", "user" ] 
    }

    Payload会被Base64Url编码为JWT的第二部分。即为:

    $ echo -n '{"iat":1593955943,"exp":1593955973,"uid":10,"username":"test","scopes":["admin","user"]}'|base64
    eyJ1c2VybmFtZSI6InRlc3QiLCJpYXQiOjE1OTM5NTU5NDMsInVpZCI6MTAsImV4cCI6MTU5Mzk1NTk3Mywic2NvcGVzIjpbImFkbWluIiwidXNlciJdfQ
    注意:对于已签名的令牌,此信息尽管可以防止篡改,但任何人都可以读取。除非将其加密,否则请勿将机密信息放入JWT的有效负载或报头元素中。

    1.1.3 Signature

    Signature部分的生成需要base64编码之后的Header,base64编码之后的Payload,密钥(secret),Header需要指定签字的算法。

    例如,如果要使用HMAC SHA256算法,则将通过以下方式创建签名:

    HMACSHA256(
      base64UrlEncode(header) + "." +
      base64UrlEncode(payload),
      secret)

    整合在一起

    输出是三个由点分隔的Base64-URL字符串,可以在HTML和HTTP环境中轻松传递这些字符串,与基于XML的标准(例如SAML)相比,它更紧凑。

    "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRlc3QiLCJpYXQiOjE1OTM5NTU5NDMsInVpZCI6MTAsImV4cCI6MTU5Mzk1NTk3Mywic2NvcGVzIjpbImFkbWluIiwidXNlciJdfQ.VHpxmxKVKpsn2Iytqc_6Z1U1NtiX3EgVki4PmA-J3Pg"

    JWT是无状态授权机制,服务器的受保护路由将Header中检查有效的token,如果存在,则将允许用户访问受保护的资源。如果JWT包含必要的数据,则可以减少查询数据库中某些操作的需求。

    二、什么时候使用JWT(when)

    • 授权:一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。单一登录是当今广泛使用JWT的一项功能,因为它的开销很小并且可以在不同的域中轻松使用。这也是JWT最常见的方案。
    • 信息交换:JSON Web令牌是各方之间安全地传输信息的好办法。对JWT进行签名,所以您可以确保发件人是他们所说的人。由于,签名可以设置有效时长,可以验证内容是否遭到篡改。

    三、如何使用JWT(how)

    3.1 JWT工作流程

    根据下面的这张流程图来分析一下JWT的工作过程

    d8e2e3ba964743b19adc659d603f8b3d.png
    JWT 认证流程
    1. 用户登录:提供用户名和密码;
    2. JWT生成token和refresh_token,返回客户端;(注意:refresh_token的过期时间长于token的过期时间
    3. 客户端保存token和refresh_token,并携带token,请求服务端资源;
    4. 服务端判断token是否过期,若没有过期,则解析token获取认证相关信息,认证通过后,将服务器资源返回给客户端;
    5. 服务端判断token是否过期,若token已过期,返回token过期提示;
    6. 客户端获取token过期提示后,用refresh_token接着继续上一次请求;
    7. 服务端判断refresh_token是否过期,若没有过期,则生成新的token和refresh_token,并返回给客户端,客户端丢弃旧的token,保存新的token;
    8. 服务端判断refresh_token是否过期,若refresh_token已过期,则返回给客户端token过期,需要重新登录的提示。

    3.2 python+flask+JWT实战

    import time
    
    from functools import wraps
    from flask import Flask, request, jsonify
    import jwt
    from jwt import ExpiredSignatureError
    
    app = Flask(__name__)
    
    max_time = 60
    refresh_max_time = 120
    token_secret = "This is a secret"
    
    
    def verify_token(func):
        @wraps(func)
        def decorator(*args, **kwargs):
            try:
                token = request.headers["token"]
                print(token)
                data = jwt.decode(token, token_secret, algorithms=['HS256'])
                now = int(time.time())
                time_interval = now - data['time']
    
                if time_interval >= max_time:
                    # create new token
                    token, refresh_token = creat_token()
                    return jsonify({"token": token, "refresh_token": refresh_token})
            except ExpiredSignatureError:
                return "Token expired"
            except Exception as ex:
                print(ex)
                return "Log in again"
    
            return func(*args, **kwargs)
    
        return decorator
    
    
    def creat_token(uid):
        now = int(time.time())
        payload = {'uid': uid, 'time': now, 'exp': now + max_time}
        refresh_payload = {'uid': uid, 'time': now, 'exp': now + refresh_max_time}
        token = jwt.encode(payload, token_secret, algorithm='HS256')
        refresh_token = jwt.encode(refresh_payload, token_secret, algorithm='HS256')
        return token, refresh_token
    
    
    @app.route('/login', methods=["POST"])
    def login():
        user_name = request.values.get('user_name')
        password = request.values.get('password')
        # @TODO 根据user_name和password 获取唯一的uid
        uid = 10
        token, refresh_token = creat_token(uid=uid)
        return jsonify({"token": token, "refresh_token": refresh_token})
    
    
    @app.route('/test', methods=['GET'])
    @verify_token
    def test():
        return 'hello world'
    
    
    if __name__ == "__main__":
        app.run(host="0.0.0.0", port=5000)

    3.3 第三方库-itsdangerous

    3.3.1 isdangerous简介

    itsdangerous支持JSON Web 签名 (JWS),内部默认使用了HMAC和SHA1来签名,其中类JSONWebSignatureSerializer内部与JWT一致,也分成三部分(header,payload,signature),查看源码可知:

    def dumps(self, obj, salt=None, header_fields=None):
            """Like :meth:`.Serializer.dumps` but creates a JSON Web
            Signature. It also allows for specifying additional fields to be
            included in the JWS header.
            """
            header = self.make_header(header_fields)
            signer = self.make_signer(salt, self.algorithm)
            return signer.sign(self.dump_payload(header, obj))
    def dump_payload(self, header, obj):
            base64d_header = base64_encode(
                self.serializer.dumps(header, **self.serializer_kwargs)
            )
            base64d_payload = base64_encode(
                self.serializer.dumps(obj, **self.serializer_kwargs)
            )
            return base64d_header + b"." + base64d_payload
    • obj保存用户相关信息,类似JWT中的payload
    • base64url对obj和header进行编码之后,使用.拼接
    • 将拼接之后的数据,作为signer的输入以及初始化__init__中用户定义的secret来生成新的token

    感兴趣的朋友可以直接参看github源码,这里不再展开赘述。

    3.3.2 python+flask+isdangerous实战

    import time
    
    from functools import wraps
    from flask import Flask, request, jsonify
    from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, SignatureExpired
    
    app = Flask(__name__)
    
    max_time = 60
    refresh_max_time = 120
    token_secret = "This is a secret"
    
    
    def verify_token(func):
        @wraps(func)
        def decorator(*args, **kwargs):
            try:
                token = request.headers["token"]
                print(token)
                s = Serializer(token_secret)
                data = s.loads(token)
                now = int(time.time())
                time_interval = now - data['time']
    
                if time_interval >= max_time:
                    # create new token
                    token, refresh_token = creat_token()
                    return jsonify({"token": token, "refresh_token": refresh_token})
    
            except SignatureExpired:
                return "Token expired"
            except Exception as ex:
                print(ex)
                return "Log in again"
    
            return func(*args, **kwargs)
    
        return decorator
    
    
    def creat_token(uid):
        now = int(time.time())
        s = Serializer(token_secret, expires_in=max_time)
        token = s.dumps({"uid": uid, "time": now}).decode("ascii")
        refresh_s = Serializer(token_secret, expires_in=refresh_max_time)
        refresh_token = refresh_s.dumps({"uid": uid, "time": now}).decode("ascii")
    
        return token, refresh_token
    
    
    @app.route('/token', methods=["POST"])
    def token():
        user_name = request.values.get('user_name')
        password = request.values.get('password')
        # @TODO 根据user_name和password 获取唯一的uid
        uid = 10
        token, refresh_token = creat_token(uid=uid)
        return jsonify({"token": token, "refresh_token": refresh_token})
    
    
    @app.route('/test', methods=['GET'])
    @verify_token
    def test():
        return 'hello world'
    
    
    if __name__ == "__main__":
        app.run(host="0.0.0.0")

    TimedJSONWebSignatureSerializer相比JSONWebSignatureSerializer在header中赠加了过期时间,如果过期会抛出SignatureExpired异常。

    四、问题

    4.1 用户登出,如何设置token无效?

    JWT是无状态的,用户登出设置token无效就已经违背了JWT的设计原则,但是在实际应用场景中,这种功能是需要的,那该如何实现呢?提供几种思路:

    • 用户登出,浏览器端丢弃token
    • 使用redis数据库,用户登出,从redis中删除对应的token,请求访问时,需要从redis库中取出对应的token,若没有,则表明已经登出
    为了保持数据的一致性,每一次认证都需要从redis中取出对应的token,每一次都以redis中的token为准。

    4.2 使用redis,两个不同的设备,一个设备登出,另外一个设备如何处理?

    请思考这样一种场景:

    • 同一个用户从两个设备登陆到服务端(设备1,设备2);
    • 设备1登出,删除redis中的对应的token - 设备2再次请求数据时,redis中的数据为空,需要重新登录。

    很明显,这种情况是不应该出现的,说一下自己的想法:

    • 每一个设备与用户生成唯一的key,保存在redis中,即设备1的用户登出,只删除对应的token,设备2的token仍然存在
    • 服务器端维护一个版本号,相同用户不同设备登入,版本号加1,这样保持key的唯一性(和上面差不多)

    欢迎大家【关注】我,我们一起学习进步。

    另外,有问题大家评论区讨论,积极沟通。

    如果本文对你有帮助,不要忘记【点赞】【收藏】,拒绝伸手党!

    展开全文
  • JSON Web Token (JWT) 作为一个开放的标准 (RFC 7519) 定义了一种简洁自包含的方法用于通信双方之间以 JSON 对象的形式安全的传递信息。因为有数字签名,所以这些通信的信息能够被校验和信任。JWT 可以使用秘钥...

    11a03d9e80e346004a18afa4618ec6a3.png

    什么是 JSON Web Token(JWT)?

    JSON Web Token (JWT) 作为一个开放的标准 (RFC 7519) 定义了一种简洁自包含的方法用于通信双方之间以 JSON 对象的形式安全的传递信息。因为有数字签名,所以这些通信的信息能够被校验和信任。

    JWT 可以使用秘钥(secret)进行签名 (使用 HMAC 算法) 或使用 RSAECDSA 算法的公钥/私钥对(public/private key)。

    尽管 JWT 可以在通讯的双方之间通过提供秘钥(secret)来进行签名,我们将会更多关注 **已签名(signed)**的 token。

    通过签名的令牌可以验证其中数据的 完整性(integrity) ,而加密的令牌可以针对其他方 隐藏(hide) 申明。

    当令牌(token)使用 公钥/私钥对(public/private key)进行签名的时候,只有持有私钥进行签名的一方是进行签名的。

    关键术语的中英文对照

    • token - 令牌
    • secret - 秘钥
    • signature - 签名
    • claims - 要求或者数据
    展开全文
  • JWT生成的Token是一个用两个点(.)分割的长字符串; 分割成的三部分分别是Header头部,Payload负载,Signature签名 即 Header.Payload.Signature JWT是不加密的,任何人都可以读的到其中的信息,其中第一部分 ...
  • 支持跨域访问: Cookie是不允许垮域访问的,这一点...Token 自身包含了所有登录用户的信息,只需要在客户端的cookie或本地介质存储 状态信息. 更适用CDN: 可以通过内容分发网络请求你服务端的所有资料(如:javascrip...
  • 1. 什么是JSON Web TokenJSON Web Token是一个开放的、行业规范(RFC7519)的方法,用于通信双方进行可靠的数据...JSON Web Token包含三部分信息数据,Header.Payload.Signature其中,Header:数据头部,声明Token类型...
  • 最近在做公司的认证系统,总结...而cookie本身不包含用户信息,它指向的是服务器上用户的 session,而由session保存用户信息。这点差别,决定token可以很容易的跨服务器,只要不同服务器实现相同解密算法即可;而cook.
  • 在前端对后端进行访问时,后端生成一个用base64加密的token串(包含个人信息过期时间和签名)返还给前端。2.前端第接收到token并储存在前端。3.前端再次访问是request请求携带token串 (一般放在http的请求头里面)4....
  • JSON Web Token(JWT)是一个开放式标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间以JSON对象安全传输信息。这些信息可以通过数字签名进行验证和信任。可以使用秘密(使用HMAC算法)或使用RSA的公钥/...
  • JSON Web Token

    2019-10-08 04:48:22
    JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。 2. 什么时候你应该用JSON ...
  • Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).**定义了一种简洁的,自包含的方法用于通信双方之间以JSON对象的形式安全的传递信息。**因为数字签名的存在,...
  • 什么是JWTJson Web Token(JWT):JSON网络令牌,是为了在网络应用环境间传递声明而制定的一种基于JSON的开放标准((RFC 7519)。JWT是一个轻便的安全跨平台传输格式,定义了一个紧凑的自包含的方式用于通信双方之间...
  • JWT token认证

    2019-02-26 10:05:51
    什么是JSON Web Token JWT 是 Json Web Tokens 的缩写,与传统 Web 的 ...而 JWT 的 token 分3个部分,首先是头部 ,表明这是一个JWT,并指明加密方式,第二部分是负载,其中可以包含 账户名、ID、邮箱等用户信息...
  • JSON Web Token(JWT)是一个开放式标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间以JSON对象安全传输信息。这些信息可以通过数字签名进行验证和信任。可以使用秘密(使用HMAC算法)或使用RSA的...
  • 生成token的方式

    2020-12-02 11:18:49
    token的最基本信息包含类型和用的算法。比如 { "type":"JWT", "alg":"HS256" } 荷载/载荷: 是核心,自定义的数据,一般是用户id,过期时间等 { "uid":"XXXXid", "exp":"122223" } 签名: 就是头部和荷载...
  • Access Token 机制详解

    2021-02-09 10:55:21
    我们在访问很多大公司的开放 api 的时候,都会发现这些 api 要求传递一个 access...令牌里面包含哪些信息呢?答案是:  哪个用户 在什么时候 授权给哪个app 去做什么事情  当然这些信息是不能直接从 access ...
  • 什么是JWTJson web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).定义了一种简洁的,自包含的方法用于通信双方之间以JSON对象的形式安全的传递信息。因为数字签名的存在...
  • JWT token权限验证

    2019-04-06 01:37:38
    JSON Web Token(JWT)是一个开放式标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间以JSON对象安全传输信息。这些信息可以通过数字签名进行验证和信任。可以使用秘密(使用HMAC算法)或使用RSA的...
  • SpringBoot 2.1.4集成JWT实现token验证 编者: wRitchie(吴理琪) 来源:http://www.bj9420.com什么...定义了一种简洁的,自包含的方法用于通信双方之间以JSON对象的形式安全的传递信息。因为数字签名的存在,这些信...
  • JSON Web Token 初识

    2021-01-03 20:52:09
    1. JSON Web Token什么 是一个开发标准,定义了一种紧凑型的、自包含的方式,用于JSON对象在各方之间安全的传输信息。 2. JWT的组成 JWT = header + payload + signature 2.1 header header:申明类型和加密算法,...
  • Token 是在服务端产生的,当客户端传来的用户名/密码验证通过时,就会在服务器端生成一个Token返回给客户端,这个Token包含了用户信息、过期时间等信息。客户端接收到返回的token后将其保存,在有效时间内客户端向...
  • JSON Web Token 入门教程

    2019-03-24 23:09:00
    JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。 2. 什么时候你应该用JSON Web ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 386
精华内容 154
关键字:

token包含什么信息