前言
登录认证

因为认证是后端的功能,所以我这个不专业的前端在实现这个功能的时候不会深究太多。所以在记录的过程中没有过多的原理,着重记录实现过程和这个过程中遇到的问题以及解决方案。

如果对登录这块前后端流程原理不太懂的,可以先做一点功课,或者直接看我的整个操作和结果,看完之后会从结果和现象出发,在去理解学习登录认证原理就会更容易。

初始的环境介绍

前端框架

Vueaxios

后端项目

pythondjangorest-frameworkcentosPostgreSQL2.7.51.10.1

关于后端数据库的一些说明

PostgreSQLpython manage.py migrate
10
auth_userdjango

我们查看一下这个表结构。

表里面暂时没有什么数据。

python manage.py createsuperuser

用户创建成功,此时在去查询数据表,就有一条用户信息了。

接下来就是登录验证的实现了。

后端Django项目配置

Django登录认证配置

setting.pyINSTALLED_APPSAPP
INSTALLED_APPS = [
    ...
    'rest_framework.authtoken'
]

设置全局的认证方案

setting.py
# 设置全局身份认证方案
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',  # token认证
    )
}

数据库同步

python manage.py migrate

在此查看数据库:

authtoken_token

简单测试

APIHTTP 401未经授权
setting全局身份认证方案
# 设置全局身份认证方案
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',  # token认证
    )
}
DEFAULT_PERMISSION_CLASSES

这块可以看 👉官方文档 的说明

API
401

经过一阵思考后的再次测试

IsAuthenticatedsetting
# 设置全局身份认证方案
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    # 'DEFAULT_AUTHENTICATION_CLASSES': (
    #     'rest_framework.authentication.TokenAuthentication',  # token认证
    # )
}
用户认证权限认证授权配置
API403
TokenAuthentication如果没有配置DEFAULT_PERMISSION_CLASSES就是允许用户无限制访问,不管我们的请求是被认证或未认证的。

所以如果需要进行用户认证,那必须的也配上权限验证,用户认证才会生效。

这个仅仅是自己的一个尝试

后端Django项目实现登录API

接着我们来实现后端的登录接口

创建一个新的app

django-admin startapp userAuth

在views.py中编写登录逻辑

# -*- coding: utf-8 -*-
# Create your views here.

from django.contrib import auth

from rest_framework.permissions import AllowAny
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
from rest_framework.decorators import api_view, authentication_classes, permission_classes

@api_view(['POST'])
@permission_classes((AllowAny,))
@authentication_classes(())
def login(request):
    """登录"""
    result = True
    errorInfo = u''
    detail = {}
    data = request.data
    username = data.get('username')
    password = data.get('password')
    
    # 调用django进行用户认证 
    # 验证成功 user返回<class 'django.contrib.auth.models.User'>
    # 验证失败 user返回None
    user = auth.authenticate(username=username, password=password)
    print "user",user
    if user == None:
        result = False
        errorInfo = u'用户名或密码错误'
        return Response({"result": result, "detail": detail, "errorInfo": errorInfo})
    
    # 用户名和密码验证成功
    # 获取用户的token 如果没有token ,表示时用户首次登录,则进行创建,并且返回token
    try:
        tokenObj = Token.objects.get(user_id=user.id)
    except Exception as e:
        # token 不存在 说明是首次登录
        tokenObj = Token.objects.create(user=user, token=token)
    # 获取token字符串
    token = tokenObj.key
    return Response({"result": result, "detail": {'token': token}, "errorInfo": errorInfo})

那登录的简单代码逻辑就写好了。

authtoken_token

暂时是没有任何记录,然后在产品的登录界面输入用户名和密码。

python manage.py createsuperuseradmin
tokenauthtoken_token
authtoken_token
前端关于登录的逻辑处理
vuemethods
login: function(){
      axios.post(url, this.loginForm).then(response =>{
          const {result, detail, errorInfo}  = response.data;
          if(result == true){
              // 登录成功
              // 设置token
              localStorage.setItem('token', detail.token);
              // 跳转页面
              this.$router.push('/certMake');
          }else{
              this.$message({
                  showClose: true,
                  message: errorInfo,
                  type: 'error'
              });
          }
      });
  }
localStoragetoken
APItoken
APItoken
token
// 别的模块的请求
getCertList: function(){
      const url = '/api/cert/certManage/certList';
      // 从localStorage获取到登录时保持的token
      const auth = 'Token ' + localStorage.getItem('token');
      const header = {'Authorization':auth}
      axios.get(url, {'headers': header}).then(response =>{
          console.log(response.data);
          const {result, detail, errorInfo}  = response.data;
          if(result == true){
             this.certList = detail.certList;
          }else{
              this.$message({
                  showClose: true,
                  message: errorInfo,
                  type: 'error'
              });
          }
      });
}

然后在重新请求上面的API。

token200

那说明我们的登录页面已经成功啦。

结语

那本篇文章是不是非常简单呢(实际的我在尝试的过程中差点头秃🔥),但是还是有些功能是需要优化改进的。

那下一篇文章的内容会梳理以下几点:

1. 优化axios:请求封装、认证信息设置的封装 
2. 注销  
3. 设置token过期时间  
参考文章

👉 django-rest-framework官方文档#权限篇
👉 django-rest-framework官方文档#授权认证篇