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

JWT 认证

时间:2020-04-11 23:58:27      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:用户密码   auth   exist   elf   base64   router   $set   code   error   

1. JWT工作原理

"""
1) jwt = base64(头部).base(载荷).hash256(base64(头部).base(载荷).密钥)
2) base64是可逆的算法、hash256是不可逆的算法
3) 密钥是固定的字符串,保存在服务器
"""

2. 安装

官网

http://jpadilla.github.io/django-rest-framework-jwt/

安装

pip install djangorestframework-jwt

3. 用法

在您的中 settings.py ,添加 JSONWebTokenAuthentication 到 Django REST 框架的 DEFAULT_AUTHENTICATION_CLASSES

REST_FRAMEWORK = {
    DEFAULT_PERMISSION_CLASSES: (
        rest_framework.permissions.IsAuthenticated,
    ),
    DEFAULT_AUTHENTICATION_CLASSES: (
        rest_framework_jwt.authentication.JSONWebTokenAuthentication,
        rest_framework.authentication.SessionAuthentication,
        rest_framework.authentication.BasicAuthentication,
    ),
}

# 设置token失效时间
import datetime 
JWT_AUTH = {
  # 过期时间
  ‘JWT_EXPIRATION_DELTA‘: datetime.timedelta(days=1),
  # 自定义认证结果:见下方序列化user和自定义response
  ‘JWT_RESPONSE_PAYLOAD_HANDLER‘: ‘user.utils.jwt_response_payload_handler‘,
}
 

序列化 user  自己创建

from rest_framework import serializers
from . import models
class UserModelSerializers(serializers.ModelSerializer):
    class Meta:
        model = models.User
        fields = [username]

自定义response

# 用处:你登陆成功之后 显示欢迎谁回来  在上面 要配置
from
.serializers import UserModelSerializers def jwt_response_payload_handler(token, user=None, request=None): return { status: 0, msg: ok, data: { token: token, user: UserModelSerializers(user).data } }

基于jwt的全局认证

import jwt
from rest_framework.exceptions import AuthenticationFailed
from rest_framework_jwt.authentication import jwt_decode_handler
from rest_framework_jwt.authentication import get_authorization_header
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication

class JSONWebTokenAuthentication(BaseJSONWebTokenAuthentication):
    def authenticate(self, request):
        jwt_value = get_authorization_header(request)

        if not jwt_value:
            raise AuthenticationFailed(Authorization 字段是必须的)
        try:
            payload = jwt_decode_handler(jwt_value)
        except jwt.ExpiredSignature:
            raise AuthenticationFailed(签名过期)
        except jwt.InvalidTokenError:
            raise AuthenticationFailed(非法用户)
        user = self.authenticate_credentials(payload)

        return user, jwt_value

全局启用 settings

REST_FRAMEWORK = {
    # 认证模块
    DEFAULT_AUTHENTICATION_CLASSES: (
        user.authentications.JSONWebTokenAuthentication,
    ),
}

局部启用禁用:任何一个cbv类的首行

# 局部禁用
authentication_classes = []

# 局部启用
from user.authentications import JSONWebTokenAuthentication
authentication_classes = [JSONWebTokenAuthentication]

多方式登陆

import re
from .models import User
from django.contrib.auth.backends import ModelBackend
class JWTModelBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            if re.match(r^1[3-9]\d{9}$, username):
                user = User.objects.get(mobile=username)
            else:
                user = User.objects.get(username=username)
        except User.DoesNotExist:
            return None
        if user.check_password(password) and self.user_can_authenticate(user):
            return user

配置多方式登陆 settings

AUTHENTICATION_BACKENDS = [user.utils.JWTModelBackend]

手动签发JWT:了解-可以拥有原生登陆基于Model类user对象签发JWT

from rest_framework_jwt.settings import api_settings

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)

VUE

             # 页面  
         <div class="inp" v-if="login_type==0"> <input v-model = "username" type="text" placeholder="用户名 / 手机号码" class="user"> <input v-model = "password" type="password" name="" class="pwd" placeholder="密码"> <div id="geetest1"></div> <div class="rember"> <p> <input type="checkbox" class="no" v-model="remember"/> <span>记住密码</span> </p> <p>忘记密码</p> </div> <button class="login_btn" @click="loginHander">登录</button> <p class="go_login" >没有账号 <span>立即注册</span></p> </div>
<script>
export default {
  name: Login,
  data(){
    return {
        login_type: 0,
        username:"",
        password:"",
        remember:false,
    }
  },
  methods:{
    loginHander(){
        // 用户密码账号登录
        this.$axios.post(`${this.$settings.HOST}/user/login/`,{
            username:this.username,
            password:this.password,
        }).then(response=>{
            if(this.remember){
                // 记住登录状态
                sessionStorage.removeItem("user_token");
                sessionStorage.removeItem("user_id");
                sessionStorage.removeItem("user_name");
                localStorage.user_token = response.data.token;
                localStorage.user_id = response.data.id;
                localStorage.user_name = response.data.username;
            }else{
                // 不记住登录状态
                localStorage.removeItem("user_token");
                localStorage.removeItem("user_id");
                localStorage.removeItem("user_name");
                sessionStorage.user_token = response.data.token;
                sessionStorage.user_id = response.data.id;
                sessionStorage.user_name = response.data.username;
            }

            // 页面跳转
            let self = this;
            this.$alert("登录成功!","某某某网站",{
               callback(){
                    self.$router.push("/");
               }
            });

        }).catch(error=>{
            this.$message.error("对不起,登录失败!请确认密码或账号是否正确!");
        });
    },
   
};
</script>

 

JWT 认证

标签:用户密码   auth   exist   elf   base64   router   $set   code   error   

原文地址:https://www.cnblogs.com/a438842265/p/12682826.html

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