Web开发 ------ 基于Django+Vue网上购物商城(三):用户认证、用户操作、用户交易 API接口设计

本文介绍了基于Django+Vue的网上购物商城中用户认证、用户操作API接口的设计,包括REST和JWT认证组件,用户手机号登录,短信验证码,用户注册,用户收藏、留言、交易等API的实现,以及Session与Token认证的差别。
摘要由CSDN通过智能技术生成

文章目录

Web开发 ------ 基于Django+Vue网上购物商城(三)

完整项目地址:https://gitee.com/dadadaliuliuliiu/ShopProject

一、用户认证API接口

但凡是一个公开使用的系统,都离不开认证登录这个模块,接下来我们完成用户登录、注册、注销等用户认证的API接口。

DRF=Django+REST+Framework

1.REST 认证组件

Django 自带一个用户认证系统,这个系统处理用户帐户、组、权限和基于 cookie 的会话。只有认证通过的用户才能访问指定的url地址。

Rest-Framework中,认证即是通过继承BaseAuthentication重构认证的类,认证的逻辑在类的authenticate方法中实现,通过判断用户传递的信息,如果认证成功返回(用户,用户Token)元组,会将用户对象封装到request里,通过request.用户可以获得用户的相关信息。具体代码实现方式如下:

(1)具体代码

1. INSTALLED_APP 中添加

#ShopProject/setting.py

# Application definition

INSTALLED_APPS = [
   
    #DRF基于token令牌认证的应用
    'rest_framework.authtoken',
 
]

REST_FRAMEWORK = {
   
    # 指定用于支持coreapi的Schema
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
    'DEFAULT_AUTHENTICATION_CLASSES': (
        # 此身份验证方案使用HTTP基本身份验证,根据用户的用户名和密码进行签名。仅用于测试。
        'rest_framework.authentication.BasicAuthentication',
        # 此身份验证方案使用Django的默认会话后端进行身份验证。# 如果前后端都是你来写的,那么可以用这个会话认证
        'rest_framework.authentication.SessionAuthentication',
        # 此身份验证方案使用基于令牌的简单HTTP身份验证方案。令牌认证适用于客户端 - 服务器设置。 #如果是前后端分离,则要用这个令牌认证
        'rest_framework.authentication.TokenAuthentication'
    )
}

2.token会生成一张表authtoken_token,数据库发生改变,所以要写入数据库

makemigrations
migrate

刷新并查看数据库,产生一条信息
在这里插入图片描述
3. 路由配置

from rest_framework.authtoken import views

urlpatterns = [
  
    path('api-token-auth/',views.obtain_auth_token)

]

views.obtain_auth_token源码理解:

obtain_auth_token = ObtainAuthToken.as_view()

返回一个token信息

class ObtainAuthToken(APIView):
   # 。。。。。。
   
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data,
                                           context={
   'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)
        return Response({
   'token': token.key})


obtain_auth_token = ObtainAuthToken.as_view()
(2) postman发送数据 测试

postman下载地址: https://www.postman.com/downloads/
postman新建POST请求操作步骤: https://jingyan.baidu.com/article/e6c8503cb7cd7de54e1a1871.html

在这里插入图片描述
在这里插入图片描述
token值会保存到数据中,跟这个用户相关联

(3)使用curl命令实现POST提交数据的测试
# -X: 指定HTTP 请求的方法, -d, --data需要提交的表单数据 
$ curl -X POST -d "username=admin&password=admin123" http://localhost:8000/api-token-auth/

用我们之前创建的admin用户来测试
模拟浏览器以post方式访问,给我们生成一个token信息

token值会保存到数据中,跟这个用户相关联
在这里插入图片描述
在这里插入图片描述

(4)REST token认证的缺点
  • Token验证是放在一张表中,即authtoken_token中,key没有失效时间,永久有效,一旦泄露,后果不可想象,安全性极差。
  • 不利于分布式部署或多个系统使用一套验证,authtoken_token是放在某台服务器上的,如果分布式部署,将失效,或多个系统用一套验证,将必须复制该表到相应服务器上,麻烦费力。

2.REST JWT 认证组件

JSON Web Token(JWT)是目前Token鉴权机制下最流行的方案。

参考资料: 前后端分离之JWT用户认证

(1) 安装模块包及 验证流程
pip install -i https://pypi.douban.com/simple djangorestframework-jwt

Github项目地址: https://github.com/jpadilla/django-rest-framework-jwt

验证流程
用户使用用户名密码来请求服务器
服务器进行验证用户的信息
服务器通过验证发送给用户一个token
客户端存储token,并在每次请求时附送上这个token值
服务端验证token值,并返回数据

(2) 配置文件和路由配置

配置文件中修改认证方式

#setting.py

REST_FRAMEWORK = {
   
    # 指定用于支持coreapi的Schema
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
    'DEFAULT_AUTHENTICATION_CLASSES': (
        # 此身份验证方案使用HTTP基本身份验证,根据用户的用户名和密码进行签名。仅用于测试。
        'rest_framework.authentication.BasicAuthentication',
        # 此身份验证方案使用Django的默认会话后端进行身份验证。# 如果前后端都是你来写的,那么可以用这个会话认证
        'rest_framework.authentication.SessionAuthentication',
        # 此身份验证方案使用基于令牌的简单HTTP身份验证方案。令牌认证适用于客户端 - 服务器设置。 #如果是前后端分离,则要用这个令牌认证
        # 'rest_framework.authentication.TokenAuthentication'
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    )
}

import datetime
JWT_AUTH={
   
    #Token失效时间, 也可以设置seconds=20 
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7), 
    #Token前缀 
    'JWT_AUTH_HEADER_PREFIX': 'JWT'
}

路由配置

    # jwt的token认证接口 
    path('jwt-auth/', obtain_jwt_token )
(3) postman发送数据 测试

在这里插入图片描述
或者使用curl命令实现POST提交数据的测试

$ curl -X POST -d "username=admin&password=admin123" http://localhost:8000/jwt-auth/
(4)JWT认证存在的问题

JWT接口它默认采用的是用户名和密码登录验证,如果用手机登录的话,就会验证失败,所以我们需要自定义一个用户验证

3.用户手机号登录API接口

(1) settings中配置

ModelBackend跟数据库类型没有关系,这是对用户认证用的。默认的认证backend会对帐号密码进行验证。默认设置如下:

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
)

当然也可以自己扩展,比如用手机号也能登录

AUTHENTICATION_BACKENDS = (
    #'django.contrib.auth.backends.ModelBackend',
    #也可以自己扩展
    'app.users.views.CustomBackend',
)
(2)用户自定义验证

默认认证的是用户名和密码,所以我们对认证进行重写

官方资料: Django 中的自定义验证

#users/views.py

from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from django.shortcuts import render


User=get_user_model()
class CustomBackend(ModelBackend):
    '''
    自定义用户认证
    '''
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            #用户名和手机都能登陆
            user=User.objects.get(
                Q(username=username) | Q(mobile=username))
            if user.check_password(password):
                return user
        except Exception as e:
            return None
(3)postman测试: 能否通过用户名和电话号码登录?

用户名登陆
在这里插入图片描述
电话号码测试:

登陆后台添加电话来测试
在这里插入图片描述
在这里插入图片描述

  • postman测试
    得到token信息
    在这里插入图片描述
  • 在浏览器端测试

修改url

#urls.py

urlpatterns = [

    path('login/',obtain_jwt_token),

    # # 商品列表页, 删除前两种商品列表页的url配置.
    # # path('goods/', GoodsListView.as_view(), name='goods-list-rest')
    # path('api-token-auth/',views.obtain_auth_token),
    # # jwt的token认证接口
    # path('jwt-auth/', obtain_jwt_token )

]

浏览器测试
在这里插入图片描述

可能报错

电话号码登陆不成功。
原因:配置文件中没有使用自定义的配置文件,或者用户没有手机号码信息。

4.拓展: 短信验证码

很多网站或者手机APP注册时需要手机号来验证身份,验证时需要验证码。本节介绍如何实现验证码功能?

常见的短信验证码服务平台:腾讯云(免费100条/月)、云片网、网易云、阿里云等。

(1)注册

“访问云片网” -> “注册” -> “开发认证” -> “签名管理” -> “模板管理”
还要添加iP白名单,测试就用本地ip,部署的时候一定要换成服务器的ip

步骤如下:
登陆云片网,生成短信的API-key。(开发者认证时长半个小时)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
将ip地址加入白名单中
在这里插入图片描述

(2)云片网发送短信API说明

在这里插入图片描述

(3)发送验证码
#users/sms.py

import json
import string
import random

import requests


class YunPian(object):
    def __init__(self,api_key):
        self.api_key=api_key
        self.single_send_url=\
            'https://sms.yunpian.com/v2/sms/single_send.json'  #在云片网文档中查看
    def send_sms(self,code,mobile):
        # 需要传递的参数
        parmas = {
   
            "apikey": self.api_key,
            "mobile": mobile,
            "text": "【刘欢test】您的验证码是{code},如非本人操作,请忽略本短信".format(code=code)
        }   #注意这里一定要加【刘欢test】,否则会使用子账号默认签名下发
        # 向API发送post请求
        response = requests.post(self.single_send_url, data=parmas)
        # 获取响应数据, 默认响应的信息时json字符串。 {'code':0, 'msg': '发送成功'}
        re_dict = json.loads(response.text)
        return re_dict

    @staticmethod
    def generate_code(count=6):
        """生成指定长度验证码"""
        return "".join(random.sample(string.digits, count))

if __name__ == '__main__':
    api_key = 'd29fcc12744b8208c8383dc2c7f4c457' #这里了在云片网管理控制平台复制APIKEY
    yunpian = YunPian(api_key=api_key)
    # 生成验证码
    code = yunpian.generate_code()
    # 发送验证短信
    result = yunpian.send_sms(code, '13679127704')
    print(result)

#运行结果:
{
   'code': 0, 'msg': 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值