DRF 认证
DRF 认证
解决你是谁的问题。
REST framework 提供了一些开箱即用的身份验证方案,并且还允许你实现自定义方案。
DRF提供的认证方案
-
class BasicAuthentication(BaseAuthentication):
-
class SessionAuthentication(BaseAuthentication):
-
class TokenAuthentication(BaseAuthentication):
-
class RemoteUserAuthentication(BaseAuthentication):
自定义Token认证
表
定义一个用户表和一个保存用户Token的表:
class UserInfo(models.Model):
username = models.CharField(max_length=32)
password = models.CharField(max_length=32)
type = models.SmallIntegerField(
choices=((1, '普通用户'), (2, 'VIP用户')),
default=1,
)
class Token(models.Model):
user = models.OneToOneField(to='UserInfo')
token_code = models.CharField(max_length=128)
定义注册登录视图
class RegisterView(APIView):
def post(self, request):
res = {"code": 0}
username = request.data.get('username')
password = request.data.get('password')
if username and password:
models.UserInfo.objects.create(username=username, password=password)
else:
res['code'] = 1
res['error'] = '用户名或密码为空'
return Response(res)
class LoginView(APIView):
"""
校验用户名密码是否正确从而生成token的视图
"""
def post(self, request):
res = {"code": 0}
username = request.data.get('username')
password = request.data.get('password')
user = models.UserInfo.objects.filter(username=username, password=password).first()
if user:
# 生成token
token = uuid.uuid1()
models.Token.objects.update_or_create(defaults={'token_code': token}, user=user)
res['token'] = token
else:
res["code"] = 1
res['error'] = '用户名或密码错误'
return Response(res)
路由
urlpatterns = [
url(r'^register/$', views.RegisterView.as_view()),
url(r'^login/$', views.LoginView.as_view()),
]
定义一个认证类
class MyAuth(BaseAuthentication):
def authenticate(self, request):
if request.method in ["POST", "PUT", "DELETE"]:
request_token = request.data.get("token", None)
if not request_token:
raise AuthenticationFailed('缺少token')
token_obj = models.Token.objects.filter(token_code=request_token).first()
if not token_obj:
raise AuthenticationFailed('无效的token')
return token_obj.user, request_token # request.user,request.auth
else:
return None, None
视图级别认证
局部配置的优先级高于全局的配置
class AuthorListView(ListCreateAPIView):
queryset = models.Author.objects.all()
serializer_class = AuthorModelSerializer
authentication_classes = [MyAuth, ]
全局级别认证
# 在settings.py中配置
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["auth_app.auth.MyAuth", ]
}
源码分析
- 请求 ——》urls.py ——》as_view ——》APIView的dispatch方法——》
- 在 1 initialize_request 中 已经获取到了认证类
- 在 2 initial 中 进行认证