码迷,mamicode.com
首页 > 其他好文 > 详细

登录模块

时间:2018-11-09 17:42:53      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:rbo   方式   加密   port   对比   rtc   分享   ror   获取   

认证

任何的项目都需要认证,用户输入了用户名和密码,验证通过,代表用户登录成功~~~

那HTTP请求是无状态的,下次这个用户再请求,我们是不可能识别这个用户是否登录的~~

所以我们就要有自己的方式来实现这个认证,也就是说~用户登录成功以后~~~我们给他们

生成一个随机字符串~~以后这个用户再请求~~都要携带这个随机字符串~~

我们就可以根据这个字符串进行判断这个用户是否登录~~~~

那么大家想一个问题~~就是我们给登录的用户生成的随机字符串放在哪里呢~~~

我们放哪里都可以~~目的是前端发送请求的时候带过来就可以了~~~

以前的cookie,session是我们的一种解决方案~~我们讲认证的时候也用过token的这种解决方案~~

TOKEN

用户登录成功后,生成一个随机字符串token给前端返回~~~

那么前端以后都携带这个token来访问~~这样我们只需要鉴别这个token~来做认证~~

前端如果发送请求~把token放在请求头中~~我们看下我们的认证要怎么写~~

在写认证之前,我们先把登录注册功能写了~~~

技术分享图片
# 我们要拓展之前课程模块下的用户表
class Account(models.Model):
    username = models.CharField(max_length=32, verbose_name="用户姓名", unique=True)
    password = models.CharField(max_length=32, verbose_name="用户密码")
    # head_img = models.CharField(max_length=256, default=‘/static/frontend/head_portrait/logo@2x.png‘,
    #                             verbose_name="个人头像")
    token = models.UUIDField(null=True, blank=True)

    def __str__(self):
        return self.username

    class Meta:
        verbose_name = "11-用户表"
        db_table = verbose_name
        verbose_name_plural = verbose_name
models.py 扩展之前功能模块的用户表
技术分享图片
# 创建两个视图 一个注册的 一个登录的
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from utils.base_response import BaseResponse
from .serializers import UserSerializer
from course.models import Account
import uuid
# Create your views here.


class UserView(APIView):

    # 注册用户
    def post(self, request):
        res = BaseResponse()
        ser_obj = UserSerializer(data=request.data)
        if ser_obj.is_valid():
            ser_obj.save()
            res.data = ser_obj.validated_data
        else:
            res.code = 1010
            res.data = ser_obj.errors
        return Response(res.dict)


class LoginView(APIView):

    # 登录视图
    def post(self, request):
        res = BaseResponse()
        # 这里要获取我们的用户名密码 进行验证是否有这个用户
        # 而且我们这个密码前端一定是密文传过来 我们通过密文对比进行验证
        username = request.data.get("username", "")
        password = request.data.get("password", "")
        user_obj_queryset = Account.objects.filter(username=username, password=password)
        if not user_obj_queryset:
            res.code = 1003
            res.error = "用户名或密码错误"
        try:
            token = uuid.uuid4()
            user_obj_queryset.update(token=token)
            res.data = token
        except Exception as e:
            res.code = 1004
            res.error = "生成token失败"
        return Response(res.dict)
views.py 编写登录注册视图
技术分享图片
# 给前端返回时候用的基础的Response类
class BaseResponse(object):

    def __init__(self):
        self.code = 1000
        self.error = None
        self.data = None

    @property
    def dict(self):
        return self.__dict__
utils.base_response.py
技术分享图片
# by gaoxin
from rest_framework import serializers
from course.models import Account
import hashlib

# 我们测试的时候用的重写create方法
# 真正开发前端传过来的就是加密后的密文密码
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = "__all__"

    def create(self, validated_data):
        password = validated_data["password"]
        password_salt = password + "luffy_password"
        md5_str = hashlib.md5(password_salt.encode()).hexdigest()
        user_obj = Account.objects.create(username=validated_data["username"], password=md5_str)
        return user_obj
serializers.py 注册序列化器

我们的登录注册写完后~~开始写认证~~

技术分享图片
# by gaoxin
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from course.models import Account


class MyAuth(BaseAuthentication):
    def authenticate(self, request):
        print(request.META)
        token = request.META.get("HTTP_AUTHENTICATION", "")
        if not token:
            raise AuthenticationFailed({"code": 1021, "error": "缺少token"})
        user_obj = Account.objects.filter(token=token).first()
        if not user_obj:
            raise AuthenticationFailed({"code": 1020, "error": "无效的token"})
        else:
            return user_obj, token
utils.authentication.py
技术分享图片
# 查看购物车是需要登录后才可以
# 所有这是一个需要认证的接口
class ShoppingCarView(APIView):
    authentication_classes = [MyAuth, ]
    # 展示购物车数据
    def get(self, request, *args, **kwargs):
        print(request.user)
        return Response("test")
views.py 测试用的视图

我们基于请求头的token认证就完成了~~~

 

登录模块

标签:rbo   方式   加密   port   对比   rtc   分享   ror   获取   

原文地址:https://www.cnblogs.com/mjc69213/p/9936226.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!