持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
相信只要做过类似有登录功能的,可以毫不避讳的说,认证肯定是功能里面最基础,但是也是最重要的,并且也不能抛弃的。
如果有做过登录功能,但是没有任何认证的,麻烦评论底下留个网址,相信广大网友会给你生动且形象的上一课, 让你了解知道世界的美好,人性的善良,正义的光撒满人间。
好了,言归正传,在这篇文章里面,主要是从这几个方面去进行浅析,去简单分析一下drf中认证的使用:
- drf 基础认证
- drf 自定义认证
- drf Token认证
- drf Session认证
1. drf 基础认证
从网页简单的登录请求去一步步的去触发过程。
透过一层层的drf代码,简单的看一下drf组件认证的实现过程,大致的流程图应该如下:
文字的大概描述应该类似这样子:
- 登录的请求,触发请求认证接口进入了APIView类的dispatch方法
- dispatch里执行self.initialize_request这个方法,重定义request,并且得到了自己定义的认证类对象
- 执行self.initial()方法中的self.perform_authentication, 里面运行了user方法
- 执行user方法里面的self._authenticate() 方法
- 把认证的信息返回
那么其实基础的认证流程已经走完,用简单的代码实现来说,大概应该是这样子的
class LoginView(APIView):
def post(self, request, *args, **kwargs):
data = request.data
username = data.get("username")
password = data.get("password")
user = authenticate(username=username, password=password)
if user:
return Response("认证成功")
else:
return Response("认证失败", status=500)
2. drf 自定义认证
经过上面基础认证的简单介绍,那么自定义认证其实也是基于上面去进行开发, 大体流程其实不变。
实现自定义身份验证方案,请继承 BaseAuthentication 并重写 .authenticate(self, request) 方法。 如果认证成功,该方法应返回 (user, auth) 的二元组,否则返回 None。
大概代码应该是这样子的
from django.contrib.auth.models import User
from rest_framework import authentication
from rest_framework import exceptions
class ExampleAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
username = request.META.get('X_USERNAME')
if not username:
return None
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
raise exceptions.AuthenticationFailed('No such user')
return (user, None)
# LoginView引用
class LoginView(APIView):
def post(self, request, *args, **kwargs):
...
user = ExampleAuthentication().authenticate(request)
3. drf token认证
drf 中除了基础认证外,还可以搭配使用简单的基于令牌的HTTP认证方案。
基于token 认证流程:用户登录,服务端给返回的token,并将token保存在服务端,以后再来访问时,需要携带token,服务器获取token后,再去数据库中获取token来进行校验
这个使用也很简单方便,配置起来也方便,并且比简单认证更可靠点。
settings.py文件中INSTALLED_APPS 设置 rest_framework.authtoken,全局设置
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
执行数据迁移命令会生成authtoken表,这个表就是用于存放用户的Token值
用户生成Token,一般来说,可以设置用户token值的过期时间 REST_FRAMEWORK_TOKEN_EXPIRE_MINUTES = 60 * 24, 然后在登录的时候判断是否过期。
如果过期了,则重新生成,没有过期则继续使用该token进行验证。
大致的代码如下:
class LoginView(APIView):
def post(self, request, *args, **kwargs):
data = request.data
username = data.get("username")
password = data.get("password")
user = authenticate(username=username, password=password)
if user:
# 基础认证ok,加上Token
token = Token.objects.get_or_create(user=user)[0]
# 用户token有效期验证,_expiring_token_authentication 自己写相应规则
token = _expiring_token_authentication(token=token, user=user)
return Response({"code": 200, "data": {"token": token.key, "user_id": user.id}})
else:
return Response("认证失败", status=500)
# 其他view
class SearchView(APIView):
# 视图里面设置
authentication_classes = [TokenAuthentication]
def post(self, request, *args, **kwargs):
pass
4. drf session认证
django 数据迁移的时候也会生成一个django_session的表格,这个表格就是存储这个用户的session数据的。
settings.py 文件全局配置Session认证
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
),
一般在访问admin后台登录,输入用户名密码的时候,后台会自动生成 session。
我们透过login这个一步步的去看代码,看到在登录的时候就会通过get_session_auth_hash()获取sessionid
然后把这个sessionid保存在数据库和request.session中。
如果你要自定义session的生成或者其他,那么也可以参考一下源码,然后加入自己的逻辑,进行开发,写一个自己需要的APIView。
结语
截止到这里,该讲的已经讲完了,也希望这些东西能给人一点点作用,当然,文章不是完美的,有缺漏有错的也可以提出来,我也能进一步学习。最后,如果可以,点赞支持一波也行。