美多后台准备和登录

美多后台准备

  • 后台仓库的创建

    • gitee上新建仓库meiduo_admin
    • 给meiduo_admin添加dev分支
    • 复制仓库的SSH
    • 在本地终端中对gitee上新建的仓库进行克隆git clone SSH
    • 在项目目录下,将dev分支克隆到本地git checkout -b dev origin/dev
    • 在本地创建项目分支并切换到项目分支git checkout -b 项目分支名
    • 将后台项目文件夹复制到项目目录下,再将项目文件推送到gitee
      git add ./
      git cimmit -m '说明信息'
      git push
      
  • 前端运行

    • 在前端项目文件下,执行npm run dev,开启前端服务,前端为8080端口 或者在vs code 中打开项目,运行npm run dev
    • 在浏览器进行前端访问
  • 后端运行

    • 在Pycharm中打开后台项目并配置Django虚拟环境
    • 在version control中添加git
    ctrl + k:commit
    ctrl + shift + k:push
    
    • 在终端中导入项目数据库mysql -uroot -p < *.sql
    • 在pycharm中连接数据库
    • pycharm中运行后台项目,后台端口为8000
    • 编辑运行,runserver
    • 开启redis服务
    • 在浏览器进行后端访问

美多后台登录

  • 后台项目架构
    -开发模式:前后端分离
    • 前端框架:VUE
    • 后端框架:Django REST framework
    • 功能部分:管理员登陆,数据统计,用户管理,商品管理,订单管理,权限管理
    • 主要技术:JWT用户认证,CORS跨域
  • 项目搭建:在原有项目基础上创建一个meiduo_admin的子应用,在子应用中完成后台的所有功能
    • python manage.py startapp meiduo_admin,注意manage.py所在的相对路径, 将apps右击指定为导包路径
    • 将子应用和rest_framework注册到配置文件中
  • 登录
    在后台登录时,前端与后端服务的域名不同,需要先解决跨域问题,登录后的状态保持采用jwt
    • 跨域CORS
      -前端与后端分处不同的域名,涉及到跨域访问数据的问题,因为浏览器的同源策略,默认不支持两个不同域间相互访问数据,如果需要在两个域名间相互传递数据,就要为后端添加跨域访问的支持
      • 只用CORS解决后端对跨域访问的支持,使用django-cors-headers扩展
      • 安装pip install django-cors-headers
        -添加应用,在配置文件中注册'corsheaders'
      • 中间层设置,添加在第一位,'corsheaders.middleware.CorsMiddleware'
      • 添加白名单
        #添加白名单
        # CORS
        CORS_ORIGIN_WHITELIST = (
            'http://127.0.0.1:8080',
            'http://localhost:8080',
            'http://www.meiduo.site:8080',
            'http://127.0.0.1:8000'
        )
        CORS_ALLOW_CREDENTIALS = True  # 允许携带cookie
        
    • JWT
      • 在用户注册或登录后,为了记录用户的登录状态,创建用户身份认证的凭证。这里不再使用Session认证机制,而使用Json Web Token认证机制

      • 浏览器在访问后端时,先发送options询问请求,进行跨域验证,后端允许访问并返回200,浏览器再发送post请求,与后端进行数据访问

      • session认证的三个缺点

        • session存储在Redis中,随着认证用户的增多,服务器开销增大
        • 扩展性问题:用户认证记录被保存在一台服务器内存中,再次访问,必须请求这台服务器,才能被授权,用户状态保持可能会失效,限制了负载均衡
        • CSRF:浏览器只要发送请求,就会携带cookie,基于cookie用来用户识别,一旦被截获,用户很容易受到跨站请求伪造的攻击
      • 基于token的认证机制,针对session认证的三个缺点

        • token存储在浏览器的storage中,对后端服务器开销无影响
        • 扩展性:解密token的的代码相同,不影响服务器扩展
        • 安全:同域名的前端js代码才能提取token
      • JWT构成,三部分信息构成,三段信息文本由.连接构成JWT字符串

        • 第一部分为头部(header),含声明类型(jwt)和加密算法(sha256)

          {
            'typ': 'JWT',
            'alg': 'HS256'
          }
          再对头部进行base64加密,构成第一部分
          
        • 第二部分为载荷(payload),存放有效信息,有效信息包含三部分

          • 标准中注册的声明

            iss: jwt签发者
            sub: jwt所面向的用户
            aud: 接收jwt的一方
            exp: jwt的过期时间,这个过期时间必须要大于签发时间
            nbf: 定义在什么时间之前,该jwt都是不可用的.
            iat: jwt的签发时间
            jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避    重放攻击。
            
          • 公共的声明:公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密

          • 私有的声明:私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息

          {
            "sub": "1234567890",
            "name": "John Doe",
            "admin": true
          }
          再对其进行base64加密,构成第二部分
          
        • 第三部分为签证(signature),这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分
          -secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了

          • header (base64后的)
          • payload (base64后的)
          • secret
        • 服务器验证token的流程


          jwt.png
      • 总结

        • 因为json通用,JWT是可以进行跨语言支持的,像JAVA,JavaScript,NodeJS,PHP等很多语言都可以使用
        • 有了payload部分,JWT可以在自身存储一些其他业务逻辑所必要的非敏感信息
        • 便于传输,jwt的构成非常简单,字节占用很小,非常便于传输的
        • 不需要在服务端保存会话信息, 所以它易于应用的扩展
        • 安全相关
          • 不应该在jwt的payload部分存放敏感信息,因为该部分是客户端可解密的部分
          • 保护好secret私钥,该私钥非常重要
          • 如果可以,请使用https协议
      • JWT使用

        • 安装配置
          pip install djangorestframework-jwt
          
          REST_FRAMEWORK = {
              'DEFAULT_AUTHENTICATION_CLASSES': (
                  'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
                  'rest_framework.authentication.SessionAuthentication',
                  'rest_framework.authentication.BasicAuthentication',
              ),
          }
          JWT_AUTH = {          
              'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
          }   #指明token的有效期
          
        • 账号登录
          • 业务说明:验证用户名和密码,验证成功后,为用户签发JWT,前端将签发的JWT保存下来

          • 后端接口设计

            • 请求方式和路径:POST meiduo_admin/authorizations/
            • 请求参数:JSON或表单(username和pwd)
            • 返回数据:JSON(username,id和token)
          • 后端实现,重写jwt_response_payload_handler方法,因为默认的返回值只有token

            #总路由配置
            url('^meiduo_admin/', include('meiduo_admin.urls')),
            #子路由配置
            url(r'^authorizations/$', obtain_jwt_token)
            #重写jwt_response_payload_handler方法
            def jwt_response_payload_handler(token, user=None, request=None):
                #自定义jwt认证成功返回数据
                return {
                    'id': user.id,
                    'username': user.username,
                    'token': token
                }
            #配置重写的方法
            JWT_AUTH = {
                'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
                'JWT_RESPONSE_PAYLOAD_HANDLER': 'meiduo_admin.utils.jwt_response_payload_handler',
            }
            #对于管理员用户和普通用户登录进行路径判断
            from django.contrib.auth.backends import ModelBackend
            from django.http import HttpRequest
            import re
            from users.models import User
            
            
            class MeiduoModelBackend(ModelBackend):
                def authenticate(self, request, username=None, password=None, **kwargs):
                    if request is None:   #JWT中未返回request,用来判断是管理员用户
                        try:
                            user = User.objects.get(username=username, is_staff=True)
                        except:
                            return None
                        # 判断密码
                        if user.check_password(password):
                            return user
            
                    else:
                        # 变量username的值,可以是用户名,也可以是手机号,需要判断,再查询
                        try:
                            user = User.objects.get(username=username)
                        except:
                            # 如果未查到数据,则返回None,用于后续判断
                            try:
                                user = User.objects.get(mobile=username)
                            except:
                                return None
                                # return None
                        # 判断密码
                        if user.check_password(password):
                            return user
                        else:
                            return None
            
          • 前端保存token,浏览器的本地提供sessionStorage(浏览器关闭即失效)和 localStorage(长期有效) 两种

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容