作者:小土豆biubiubiu

博客园:https://www.cnblogs.com/HouJiao/

掘金:https://juejin.im/user/2436173500265335

微信公众号:土豆妈的碎碎念(扫码关注,一起吸猫,一起听故事,一起学习前端技术)

作者文章的内容均来源于自己的实践,如果觉得有帮助到你的话,可以点赞️给个鼓励或留下宝贵意见

前言

最近需要做一个登录认证的功能,所以想将整个的过程做一个记录,方便以后回头查看,同时希望给我遇到同样问题的同学一些参考。

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

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

初始的环境介绍

前端框架

框架:Vue

HTTP库:axios

后端项目

后端框架:基于pythondjango框架

WEB API:rest-framework

服务器: centos

数据库:PostgreSQL

python版本:2.7.5

django版本:1.10.1

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

数据库使用的是PostgreSQL,并且已经对数据库表进行了同步,命令为:python manage.py migrate

数据库进行同步以后,会生成10相关的数据表。

需要关注的就是auth_user表这个表,它是django框架生成的用户表,后面就使用这个表保存用户的信息。

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

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

接着我们来创建一个用户,用于后期的登录测试:python manage.py createsuperuser

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

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

后端Django项目配置

Django登录认证配置

首先我们需要在setting.py文件的INSTALLED_APPS配置登录认证的APP

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

设置全局的认证方案

接着在setting.py中配置全局身份认证方案。

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

数据库同步

上面的配置完成需要进行数据库同步:python manage.py migrate

在此查看数据库:

发现会多出来一个名为authtoken_token的数据表,这个表就是和用户认证相关的数据表。

简单测试

我们已经配置好了全局的认证方式,那按道理来说,现在任意访问后端的某个API就会出现为HTTP 401未经授权这样的错误,那我们来试一试。

那结果发现请求还是可以正常发出。

这块在网上搜索了很久,看到有网友说关于setting设置的全局身份认证方案配置有问题,正确的配置是

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

DEFAULT_PERMISSION_CLASSES是关于用户的权限配置,如果没有配置该项的话就是允许用户无限制访问,不管我们的请求是被认证或未认证的。

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

那加上这个认证以后呢,在去请求前面的API



发现这次终于有反应了,服务器端返回了401,就是用户认证失败。

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

那接着我想起前面新增的IsAuthenticated授权配置,所以将setting进行了修改。

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

即注释了全局的用户认证,保留了权限认证,测试一下这个全局的授权配置会对请求产生什么影响。

我们发现这条API返回了403,也就是访问的权限出现了问题。

那不管怎么样,在单独配置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 createsuperuser命令创建的admin账户

因为是首次登录,因此为该用户创建token,即authtoken_token会产生一条记录。

这里给大家看一看我登录成功以后的authtoken_token数据表。

前端关于登录的逻辑处理

最后就是关于前端vue处的逻辑,我们先看一下登录页面的methods逻辑。

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进行本地存储。

接着我们需要在访问其他API时将这个token设置到请求头部。

在这之前呢,我们先看一下API没有添加token时的结果。

然后将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。

可以看到请求头部已经添加上了token,而且响应的状态码也是200

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

结语

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

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

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

关于

作者

小土豆biubiubiu

一个努力学习的前端小菜鸟,知识是无限的。坚信只要不停下学习的脚步,总能到达自己期望的地方

同时还是一个喜欢小猫咪的人,家里有一只美短小母猫,名叫土豆

博客园

https://www.cnblogs.com/HouJiao/

掘金

https://juejin.im/user/2436173500265335

微信公众号

土豆妈的碎碎念

微信公众号的初衷是记录自己和身边的一些故事,同时会不定期更新一些技术文章

欢迎大家扫码关注,一起吸猫,一起听故事,一起学习前端技术

作者寄语

小小总结,欢迎大家指导~

参考文章

django-rest-framework官方文档#权限篇

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

最新文章

  1. 设计模式--装饰模式Decorate(结构型)
  2. C# Form.Close 的释放问题
  3. .Net开源网络爬虫Abot介绍
  4. springMVC 拦截器简单配置
  5. poj 1318
  6. response.setCharacterEncoding方法未定义
  7. WPF自定义控件(二)——TextBox
  8. 又是干货,这个春节感觉吃饱了。各方面---RHCS集群理论
  9. socket编程2
  10. exists
  11. web前端简介
  12. MM们,你们为什么要找一个程序猿男票?
  13. phpcms v9 sql注入脚本
  14. Java学习笔记3(数组)
  15. JS获取访客IP+判断归属地+自动跳转
  16. date简述
  17. javascript 中的==(相等运算符)与===(等同运算符)比较
  18. SpringMVC零碎笔记
  19. C++程序文件链接
  20. zookeeper集群的搭建

热门文章

  1. 7.hbase shell命令 cmd
  2. Goland远程连接Linux开发调试
  3. .NET 设计模式 思维导图
  4. Java多线程_Atomic
  5. neighbor和neigh_modify(转载)
  6. Http请求-okhttp3基本用法
  7. java安全编码指南之:基础篇
  8. 区块链入门到实战(37)之Solidity – 循环语句
  9. ASP.NET Core3.1使用IdentityServer4中间件系列随笔(二):创建API项目,配置IdentityServer保护API资源
  10. Vue基础(三)---- 组件化开发