首页 > 其他分享 >session与token

session与token

时间:2023-08-05 23:11:22浏览次数:35  
标签:Session base64 token session key print payload

1. base64

  Base64是一种用于将二进制数据编码为文本的编码方案,它使用ASCII字符串格式来表示二进制数据。Base64常用于在只能处理ASCII字符的系统上传输数据,如电子邮件系统、web服务器以及编码媒体文件。在Base64中,每个字符代表6个数据位,因此可以将3个字节的二进制数据编码为4个字符。这种编码方案被用于多种用途。具体的编码方式入下:

 

具体编码步骤如下:

  1.将字符串拆成每三个字符一组

  2.计算每一个字符对应的ASCII码的二进制

  3.将8位二进制码,按照每6位一组重新分组,不足6位的后面补0.

  4.计算对应的十进制编码

  5.按照base64表,查看对应的字符。

  如果编码不足3个ASCII字符(3*8=24)的长度,多余的部分补0到6个,最后面没有的补base字符为'='字符。具体如下:

  也就是说base64字符串个数是4的倍数。关于base64的主要方法如下:

2. 代码

"""
base64是一种编码技术
base64所有方法的参数和结果都是字节串
"""
import base64
#1.编码:明文---》base64
r1=base64.b64encode(b"wa")
  #print(r1)#b'd2E='
print(r1.decode())#d2E=

username="wangxi"
r2=base64.b64encode(username.encode())#username.encode()变为字节串
print(r2)#b'd2FuZ3hp'
#2.解码
r22=base64.b64decode(r2)
print(r22)#b'wangxi'

  使用base64,可以将明文按照base64的特定规则转换为base64编码,但是仍然能反向破解。对于真正的不可逆向的加密得使用md5、sha256等算法。

3. session

  在Web开发中,Session是一种用于跟踪用户会话的机制,以实现用户在不同请求之间的状态保持和数据共享。它通过在服务器端存储和管理用户相关数据,并通过一个唯一的标识符将会话与用户关联起来。工作原理如下:

  1. 用户在浏览器中发送一个HTTP请求到服务器,并携带一个唯一的标识符,通常称为Session ID。
  2. 服务器接收到请求后,根据Session ID查找关联的Session数据。如果找到了,则表示该用户存在会话,可以获取和修改Session中的数据。如果没有找到,则表示该用户是新用户,需要创建一个新的Session,并生成一个唯一的Session ID,同时会创建一个特殊的cookie。
  3. 服务器将Session ID作为Cookie的一部分发送给浏览器。浏览器在后续的请求中会自动将这个Cookie携带上来。
  4. 用户的后续请求在Cookie中携带了Session ID后,服务器会根据Session ID和服务器内存中存放的Session ID进行比对,获取关联的Session数据,并对其进行操作。
  5. 当用户会话结束(如关闭浏览器或超过Session过期时间)时,服务器会销毁该会话,删除对应的Session数据。

通过Session,Web应用可以实现以下功能:

  • 跟踪用户的登录状态,实现用户认证和授权。
  • 存储用户的个性化信息,如首选语言、主题等。
  • 在多个页面之间共享数据,如购物车内容、表单数据等。
  • 限制用户的访问权限,如设置Session超时时间等。

  需要注意的是,Session数据存储在服务器端,对服务器的存储和处理能力有一定要求。同时,Session ID需要保持安全,以防止会话劫持等安全问题。

  这里,给出Session与Cookie的对比。

4. 散列加密算法。

  4.1 SHA-256

 

    SHA-256(Secure Hash Algorithm-256)它是一种安全散列加密算法,这里不过多介绍。其有三大特点:定长输出、不可逆、雪崩。

 

from hashlib import sha256
s = sha256() # 1.创建sha256对象
s.update(b'abcd') # 2.添加欲hash的内容,类型为 bytes
hex_result = s.hexdigest() # 3.十六进制结果(十六进制,用于存储)
print(hex_result)#88d4266fd4e6338d13b......
print(len(hex_result))#64

s.update(b'abc')#减少一个d会造成与abcd加密得结果巨大不同,’雪崩效果‘
hex_result = s.hexdigest()
print(hex_result)#8a50a4422d673f463f8e......
print(len(hex_result))#64

 

  因为加密不可逆,无法将结果转换为明文,所以很安全。

  4.2.HMAC-SHA256

  HMAC-SHA256(Hash-basedMessageAuthenticationCode)是一种通过特别计算方式之后产生的消息认证码,使用散列算法同时结合一个加密密钥。它可以用来保证数据的完整性,同时可以用来作某个消息的身份验证。

import hmac
# 1. 生成hmac对象
# 参数1:密钥key,bytes类型,
# 参数2:欲加密的串,bytes类型
# 参数3:hmac的算法,指定为SHA256
key = b'123456'
string = b'{"username":"chaogege"}'
h = hmac.new(key, string, digestmod='SHA256')
result = h.hexdigest() # 获取最终结果
print(result)#6ae909d8d5f825...
print(len(result))#64

  除了上面介绍的哈希加密算法之外,还有md5等加密算法。

5. token

  token在计算机身份认证中是令牌(临时)的意思,相对于session而言,其不需要存储用户信息,只需要对用户传过来的token信息进行计算就能达到身份认证的效果,而且防篡改能力强。为了减轻服务器频繁查询的压力,往往采用token作为令牌进行会话认证。

  5.1 JWT(json-web-token)

  JWT(JSON Web Token)是一种用于验证和在网络应用之间传递声明(claims)的开放标准(RFC 7519)。它通常用作身份验证(Authentication)和授权(Authorization)的令牌(Token)。

  JWT由三个部分组成,每个部分之间使用点号(.)分隔:

  Header(头部):包含了标识这个JWT的类型和使用的签名算法的信息。格式如下:{"alg":"HS256","typ":"JWT"}alg代表要使用的算法,typ是固定的大写JWT。

 

  Payload(载荷):包含了实际的声明(claims),例如用户的ID、权限等信息。主要常用格式如下:{"exp":设置token的过期的时间戳,"":"私有key":"值"}

 

  Signature(签名):使用指定的算法对前两个部分进行签名,以确保JWT的完整性和真实性。以下用 HS256为例sign =hmac.new(自定义的key ,

  base64后的header + b'.' + base64后的payload,digestmod="SHA256")

 

  JWT的基本工作流程如下:

  用户使用用户名和密码进行身份验证。

  服务器验证用户的凭据,并生成一个JWT作为其身份验证的令牌。

  服务器将JWT发送给客户端,并将其存储在Cookie或本地存储中。

  客户端在后续的请求中将JWT发送到服务器,以便进行授权和身份验证。

  服务器验证JWT的合法性和完整性,并根据其中的声明进行授权处理。

  JWT的设计具有以下优势:

  1.   可以在不需要存储令牌的情况下实现无状态身份验证和授权。
  2.   适用于跨域场景,因为JWT可以作为HTTP头部或URL参数在客户端和服务器之间传递。
  3.   声明(claims)可以包含有关用户的任何有用信息,并且是可自定义的。
  4.   需要注意的是,JWT令牌是基于Base64编码的,但并不是加密的。因此,令牌的内容可以被解码和读取,但不能被修改,因为任何修改都会使签名无效。

  使用JWT时需要小心保护令牌的机密信息,避免将敏感信息直接存储在载荷中,最好将敏感信息放在服务器端进行处理。此外,对于令牌的过期时间也需要进行适当的管理和更新。

  5.2 jwt校验

  1.解析header, 确认alg。
  2.签名校验 - 根据传过来的header和payload按 alg指明的算法进行签名,将签名结果和传过来的sign进行对比,若对比一致,则校验通过。
  3.获取payload自定义内容。

6.实现

  6.1自定义实现token

  对token实现一个例子:

import hmac
import json
import time
import base64

header={'alg':'HS256','typ':'JWT'}
header_str=json.dumps(header)
h=base64.b64encode(header_str.encode())
print(h)

#2.payload
#设置有效期m秒,私有声明存放用户名user
payload={"exp":time.time()+5000,"username":"wangxi"}
payload_str=json.dumps(payload)
p=base64.b64encode(payload_str.encode())
print(p)
#3.sign:签名
sign=hmac.new(
    key=b"123456",
    msg=h+b'.'+p,
    digestmod="SHA256"
).hexdigest()
print("sign",sign)
s=base64.b64encode(sign.encode())
print(s)
token=h+ b"." + p + b"." + s  #注意,拼接起来的每一个都是字节串类型
print("token",token)#b'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJleHAiOiAxNjkwOTY1NjM1LjI3NzIyNTUsICJ1c2VybmFtZSI6ICJ3YW5neGkifQ==.NWE4MWYxNTg3OThmZTQ5NTM1YWM5YWU0YTc4ZGEzZjk4MTE4ZTViNWVhMjNlMTNkNmFlMzM4MzYwNjMxMjRlMw=='

  下面是封装并检查token合法性代码

"""
jwt模块
"""
import base64
import hmac
import json
import time

class Jwt:
    def __init__(self):
        pass

    def make_token(self,payload,key):
        header={"alg":"HS256","typ":"JWT"}
        header_str = json.dumps(header)
        h_base64 = base64.b64encode(header_str.encode())
        #payload = {"exp": time.time() + 5000, "username": "wangxi"}
        payload_str = json.dumps(payload)
        p_base64 = base64.b64encode(payload_str.encode())

        sign = hmac.new(
            key=key.encode(),
            msg=h_base64 + b'.' + p_base64,
            digestmod="SHA256"
        ).hexdigest()
        s_base64 = base64.b64encode(sign.encode())
        token = h_base64 + b"." + p_base64 + b"." + s_base64
        return token


    def check_token(self,token,key):
        """
        :param token:
        :return:
        """
        h, p, s = token.split(b'.')
        sign_server = hmac.new(
            key=b'123456',
            msg=h + b'.' + p,
            digestmod="SHA256"
        ).hexdigest()  # string
        sign_server = base64.b64encode(sign_server.encode())
        if sign_server != s:
            raise Exception("token不合法")
        else:
            p_str = base64.b64decode(p)
            json_str = p_str.decode()
            p_dic = json.loads(json_str)
            exp = p_dic.get("exp")
            now = time.time()
            if now > exp:
                raise Exception("token过期了")
            else:
                print("没有过期")
        return p

if __name__ == '__main__':
    jwt=Jwt()
    payload={
        "exp":time.time()+5,
        "username":"wanxi"
    }
    key="123456"
    token=jwt.make_token(payload=payload,key=key)
    print(token)
    print(len(token))
    time.sleep(5)
    try:
        payload=jwt.check_token(token,key)
        print(payload)
        #
    except  Exception as e:
        print(e)

  6.2 pyjwt库实现token

  安装pyjwt:  pip install pyjwt -i  https://pypi.tuna.tsinghua.edu.cn/simple/

import time
import jwt
#1.生成token:jwt.encode(pay,key,algorithms)
payload={
    "exp":time.time()+5,
    "username":"wangxi",
         }
key="123456"
token=jwt.encode(payload,key)# 默认hs256 ,algorithm: str | None = "HS256",
print(token)
#2.校验token
time.sleep(6)#休眠6秒后,token失效,会报错
payload=jwt.decode(token,key,algorithms="HS256")
print(payload)

  对于pyjwt库实现生成的token,最后面永远没有==号。是为了优化处理,节省空间。检查token时可能采取了加上==的方法。

  前面代码中是这样的:print("token",token)#b'前面部分省略hmZTQ5NTM1M4MzYwNjMxMjRlMw=='。

小结:base64所有方法的参数和结果都是字节串,如果是在url中使用base64时,应该用urlsafe_b64encode与urlsafe_b64decode。http协议是不保存浏览器客户端状态的,是一种无状态连接协议。所以当我们关闭页面,在输入地址打开该页面有时候也能还原上次的页面状态,就用到了session,注意session是存储到服务器端运行内存中的,重启服务器session将丢失。不只是session,而且cookie也有失效时间,可以设置。针对cookie最多只能存储4kb数据,html5提供了一种新技术localStorage,一般支持5M的大小。另外,本文没有对cookie作过多的说明,等后期加上。如果客户端禁止了cookie的话,每次会话,session都会新创建。token相对session而言,简洁,不用对session数据进行清除管理等操作,而且当cookie被截获,其session将可能被跨站请求伪造攻击。关于加密算法,本文没有过多讨论,重在token的组成与实现。

  若存在不足或错误之处欢迎指正与评论!

 

参考资料:

https://blog.csdn.net/m0_53856016/article/details/126858443

https://blog.csdn.net/m0_61355190/article/details/126000130

标签:Session,base64,token,session,key,print,payload
From: https://www.cnblogs.com/wancy/p/17601987.html

相关文章

  • cookie和localStorage和sessionStorage的区别
    cookie和localStorage和sessionStorage的区别下面从几个方向区分一下cookie,localStorage,sessionStorage的区别生命周期:cookie:可设置失效时间,否则默认为关闭浏览器后失效。localStorage:除非被手动清除,否则永久保存。sessionStorage:仅在当前网页会话下有效,关闭页面或关......
  • cookie和服务器Session的区别
    cookie和服务器Session的区别cookie和服务器Session都可用来存储用户信息,cookie存放于客户端,Session存放于web服务器端。因为cookie存放于客户端有可能被窃取,所以cookie一般用来存放不敏感的信息,比如用户设置的网站主题。敏感的信息用Session存储,比如用户的登陆信息。Se......
  • 蓝图,flask-session,数据库连接池
    1蓝图#blueprint:蓝图,flask都写在一个文件中,项目这样肯定不行,分目录,分包,使用蓝图划分目录#不用蓝图,划分目录 -一直使用app对象,会出现循环导入问题-项目名statictemplatesorder_detail.htmlviews__init__.py......
  • go随机生成token
    const(defaultTokenLenint=16)funcGenerateToken()string{rand.Seed(time.Now().UnixNano())runes:=[]rune("abcdefghijklmnopqrstuvwxyz0123456789")b:=make([]rune,defaultTokenLen)fori:=rangeb{b[i]=r......
  • go使用jwt生成token
    常见的认证方式一般用户认证主流的方式大致上分为基于session和基于token这两种。基于sesion的认证方式用户向服务器发送用户名和密码。服务器验证通过后,在当前对话(sesion)里面保存相关数据,比如用户角色、登录时间等等。服务器向用户返回一个session_id,写入用户的Co......
  • 浅谈-HttpSession session = request.getSession(false)
    当使用request.getSession(false)方法时,如果当前请求没有关联的会话,则不会创建新的会话,而是返回null。这意味着,如果当前客户端没有携带有效的会话标识符(如JSESSIONID),或者会话已过期或被销毁,则request.getSession(false)方法将返回null。下面是一个示例来解释这个方法的用......
  • Oralce中processes和sessions的设置关系
    一,基本概念Sessions:指定了一个Instance中能够同时存在的sessions数量,或者说,就是能同时登陆到数据库的并发用户数。通常,我们设定这个参数时需要考虑我们可能会有多少个同时连接到数据库的并发用户,并加上后台进程的进程数,最后乘以1.1。processes:指定了Instance在OS层面所能同时运......
  • Cookie + session 理解
    Http是一种无状态的应用层传输协议。可以理解成请求之间没有联系。但是很多场景,比如需要知道上次是哪个用户登录了。这时就要用到cookie和session了。一.CookieCookie是一种客户端技术,可以理解成用户信息存储在客户端。客户端第一次请求服务器时,如果需要记录用户状态,就用respon......
  • flask as_view源码,请求响应,cookie,session
    1CBV1cbv写法 -1写个类,继承MethodView-2在类中写跟请求方式同名的方法-3注册路由:app.add_url_rule('/home',view_func=Home.as_view('home'))#home是endpoint,就是路由别名2cbv加装饰器 -方式一: classHome(MethodView): decorators=[auth]#......
  • 30%Token就能实现SOTA性能,华为诺亚轻量目标检测器Focus-DETR效率倍增
    前言 目前DETR类模型已经成为了目标检测的一个主流范式。但DETR算法模型复杂度高,推理速度低,严重影响了高准确度目标检测模型在端侧设备的部署,加大了学术研究和产业应用之间的鸿沟。来自华为诺亚、华中科技大学的研究者们设计了一种新型的DETR轻量化模型Focus-DETR来解决这......