Django利用drf实现jwt认证
一、cookies、session、token
1.Cookies
Cookie是一种客户端会话技术,所有数据存储在客户端,其是以key-value进行数据存储层,服务器中是不做任何存储。
Cookies使用特性:
1)支持过期时间
2)根据域名进行cookie存储
3)不能跨网站(域名)
4)不能跨浏览器
5)自动携带本网站的所有cookie
6)cookie默认不支持中文,base64
2.Session
session是一种服务端会话技术,数据都存储在服务端,默认存在内存 RAM,在django被持久化到了数据库中,该表叫做Django_session,这个表中有三个字段,分别为seesion_key、session_data、expris_date。
Django中Session的默认过期时间是14天,支持过期,主键是字符串,默认做了数据安全,使用了BASE64
session依赖于cookie
3.Token
Token 的中文意思是“令牌”。其被认为是自定义的session又或者被认为是加密的唯一字符串,主要用来身份验证。 Facebook,Twitter,Google+,Github 等大型网站都在使用。比起传统的身份验证方法,Token 有扩展性强,安全性高的特点,非常适合用在 Web 应用或者移动应用上,如果使用在移动端或客户端开发中,通常以Json形式传输,服务端会话技术,自定义的Session,给他一个不能重复的字符串,数据存储在服务器中。
Token使用流程:
1)使用基于 Token的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:
2)客户端使用用户名跟密码请求登录
3)服务端收到请求,去验证用户名与密码
4)验证成功后,服务端会签发一个Token,再把这个Token发送给客户端
5)客户端收到Token以后可以把它存储起来,比如放在 Cookie里或者Local Storage里
6)客户端每次向服务端请求资源的时候需要带着服务端签发的Token
7)服务端收到请求,然后去验证客户端请求里面带着的Token,如果验证成功,就向客户端返回请求的数据
二、Django中使用jwt机制实现登录验证
1)配置setting.py文件,需要将rest_framework导入
2)数据库结构
因为我希望token认证的是我自建的员工信息表,但我没有去setting中去更改默认django生成的user表
因为一旦更改权限表为我自建的表,那么会多出很多不必要的字段,这不是我所希望的例如以下这些字段。
所以对于密码的加密,我没有使用框架自带的加密而是去复写了加密以便可以存储到我自建的员工信息表方便token的生成。
3)注册接口序列化器配置Serlizer.py
重写序列化器中的create方法,同时记得导入加密库
这样当我们调用这个接口的时候,因为我们使用的是序列化器,当我们新建员工或者说是用户的时候就会对我们的密码进行加密并存入数据库表中。
三、jwtAuth.py文件
定义
JwtQueryParamsAuthentication类(验证类)----->对token进行验证
class JwtQueryParamsAuthentication(BaseJSONWebTokenAuthentication): def authenticate(self, request): # print("request") # print(request.META.keys()) # print(request.META.get("HTTP_TOKEN")) headers=request.META.get("HTTP_TOKEN") print("Authorization") # print(request.META.get("Authorization")) print(request.META.keys()) # 认证逻辑() # token信息可以放在请求头中,请求地址中 # key值可以随意叫 # token=request.query_params.get("token") # token放到请求地址中 salt=settings.SECRET_KEY # token放到请求头中 , key 必须为: Authorization # token = request.META.get('HTTP_Authorization'.upper()) # 校验token是否合法 try: payload = jwt.decode(headers,salt,True) #把username存入redis中 print("payload") print(payload) except jwt.ExpiredSignature: raise AuthenticationFailed('过期了') except jwt.DecodeError: raise AuthenticationFailed('解码错误') except jwt.InvalidTokenError: raise AuthenticationFailed('不合法的token') # user = self.authenticate_credentials(payload) return (payload, headers)
四、token生成函数
create_token()根据输入的,这里的加密方式是根据username,secretKey和默认的加密方式进行加密,加密方式可以更改。
具体加密的细节可以参考以下博文
https://www.cnblogs.com/Paul-watermelon/p/11286698.html
https://www.cnblogs.com/xujunkai/p/12359573.html
def create_token(payload,timeout=100): salt=settings.SECRET_KEY # 构造 headers={ 'typ':"jwt", 'alg':"HS256" } # 构造payload payload['exp']=datetime.datetime.utcnow()+datetime.timedelta(minutes=timeout) token=jwt.encode(payload=payload,key=salt,algorithm="HS256",headers=headers).decode('utf-8') return token
五、视图函数中引用
这里我使用的是局部引用,可以去setting文件中设置全局引用
起码需要继承GenericAPIView,设置了authentication之后可以像中间件一样,当每次执行当前视图函数之前进行token的合法性验证,通过了才继续往下走。
六、token的生成
登录成功之后会将该token值进行返回,你可以设置token的存在时间具体可以参考其他文章
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?