zoukankan      html  css  js  c++  java
  • 三方登陆----微博

    三方登陆流程:

    微博开放平台设置app和key

     

     

     

    请求用户授权Token: https://open.weibo.com/wiki/Oauth2/authorize

    获取授权过的Access Token, UID: https://open.weibo.com/wiki/Oauth2/access_token

    代码实现:

    vue页面代码:

    <template>
        <div>
            <p><input type="button" value="微博登陆" @click="weibo_login()"></p>
            <P><a v-if="a==2" :href="weibo_url" class="weibo_login">微博登陆</a></P>
        </div>
    </template>
    
    <script>
    import axios from 'axios'
    export default {
        name:"weibo",
        data(){
            return{
                a:1,
                weibo_url:''
            }
        },
        methods: {
            weibo_login(){
                axios({
                    url:"http://127.0.0.1:8000/wb/weibourl/",
                    method:"get"
    
                }).then(res=>{
                    this.a = 2
                    this.weibo_url = res.data.weibo_url
                })
            }
        },
        
    
    }
    </script>
    weibo.vue
    <template>
        <div>
            <h1>页面跳转中。。。</h1>
        </div>
    </template>
    
    <script>
    import axios from 'axios'
    export default {
        name:'weibo_callback',
        data(){
            return{
    
            }
        },
        methods:{
            get_code(){
                var code = this.$route.query.code
                console.log(code)
                axios({
                    url:"http://127.0.0.1:8000/wb/call_back/?code="+code,
                    method:"get"
                }).then(res=>{
                    console.log(res.data)
                    if(res.data.code==200){
                        sessionStorage.setItem("jwt_token",res.data.token)
                        window.location.href="www.baidu.com"
                    }else if(res.data.code==404){
                        sessionStorage.setItem("u_id",res.data.uid)
                        this.$router.push({path:"/binduser"})
                    }else{
                        alert("授权失败")
                    }
                    })
            }
        },
        mounted(){
            this.get_code()
        }
    }
    </script>
    weibo_callback.vue
    <template>
        <div>
            <p>用户名:<input type="text" v-model="username"></p>
            <p>密码:<input type="password" v-model="password"></p>
            <p>手机号:<input type="text" v-model="phone"></p>
            <p><input type="button" @click="send_bind_info()"></p>
        </div>
    </template>
    
    
    <script>
    document.title = "绑定页面";
    import axios from "axios";
    export default {
      // axios-> access_token
      data: function() {
        return {
          password: "",
          username: "",
          phone:""
        };
      },
      methods: {
        send_bind_info: function() {
          let post_data = new FormData();
          let u_id = sessionStorage.getItem("u_id");
          post_data.append("password", this.password);
          post_data.append("username", this.username);
          post_data.append("phone", this.phone);
          post_data.append("u_id", u_id);
          axios({
            url: "http://127.0.0.1:8000/wb/bind_user/",
            method: "post",
            data: post_data
          }).then(res => {
              console.log(res.data)
          });
        }
      }
    };
    </script>
    binduser.vue

    django代码

    import os
    
    # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    
    # Quick-start development settings - unsuitable for production
    # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = 'fivz67l6ttp5jlg%$jnrinq=j72re)x-54k(q-%y^l5+(7^h6i'
    
    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = True
    
    ALLOWED_HOSTS = []
    
    
    # Application definition
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'appqiniu',
        'rest_framework',
        'corsheaders',
        'rest_framework.authtoken',
        'users',
        'weiboapp',
        "redisapp"
    ]
    
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        # 'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'corsheaders.middleware.CorsMiddleware',
    
    ]
    
    ROOT_URLCONF = 'django_online.urls'
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')]
            ,
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
    WSGI_APPLICATION = 'django_online.wsgi.application'
    
    
    # Database
    # https://docs.djangoproject.com/en/2.2/ref/settings/#databases
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': '127.0.0.1',  # 数据库主机
            'PORT': 3306,  # 数据库端口
            'USER': 'root',  # 数据库用户名
            'PASSWORD': '123456',  # 数据库用户密码
            'NAME': 'drf1908a_ol'  # 数据库名字
        }
    }
    
    
    # Password validation
    # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
    
    AUTH_PASSWORD_VALIDATORS = [
        {
            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
        },
    ]
    
    
    # Internationalization
    # https://docs.djangoproject.com/en/2.2/topics/i18n/
    
    LANGUAGE_CODE = 'en-us'
    
    TIME_ZONE = 'UTC'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = True
    
    
    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/2.2/howto/static-files/
    
    STATIC_URL = '/static/'
    CORS_ALLOW_CREDENTIALS = True
    CORS_ORIGIN_ALLOW_ALL = True
    CORS_ORIGIN_WHITELIST = ()
    CORS_ALLOW_METHODS = (
        'DELETE',
        'GET',
        'OPTIONS',
        'PATCH',
        'POST',
        'PUT',
        'VIEW',
    )
    
    CORS_ALLOW_HEADERS = (
        'XMLHttpRequest',
        'X_FILENAME',
        'accept-encoding',
        'authorization',
        'content-type',
        'dnt',
        'origin',
        'user-agent',
        'x-csrftoken',
        'x-requested-with',
        'Pragma',
    )
    
    SESSION_ENGINE='django.contrib.sessions.backends.cache'
    
    REST_FRAMEWORK = {
        # 身份认证
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
            'rest_framework.authentication.SessionAuthentication',
            'rest_framework.authentication.BasicAuthentication',
        ),
    
        #全局配置接口权限
        # 'DEFAULT_PERMISSION_CLASSES': (
        #         'rest_framework.permissions.IsAuthenticated',
        #     ),
    
    }
    
    import datetime
    
    JWT_AUTH = {
        'JWT_AUTH_HEADER_PREFIX': 'JWT',
        'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
        'JWT_RESPONSE_PAYLOAD_HANDLER':
            'users.views.jwt_response_payload_handler',  # 重新login登录返回函数
    }
    
    AUTH_USER_MODEL='users.User'  # 指定使用users APP中的 model的User表作为系统认证时使用表
    
    
    WEIBO_APP_KEY = '505677658'
    WEIBO_APP_SECRET = '5689ef360f8e25c1df8a54e8e5653cd2'
    WEIBO_CALL_BACK = 'http://127.0.0.1:8080/#/weibo_callback/'   # 回调路由
    setting.py
    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    from django.urls import path,re_path,include
    from weiboapp import views
    from rest_framework_jwt.views import obtain_jwt_token  # 验证密码后返回token
    
    urlpatterns = [
    
    
        path('weibourl/', views.WBUrl.as_view(), ),
        path('call_back/', views.WBCallBack.as_view(), ),
        path('bind_user/', views.BindUser.as_view(), ),
    
    
    ]
    urls.py
    from rest_framework_jwt.settings import api_settings
    from rest_framework import serializers
    from users.models import User
    
    class UserSerializer(serializers.Serializer):
        id  =serializers.IntegerField(read_only=True)
        username = serializers.CharField()
        password = serializers.CharField()
        phone = serializers.CharField()
        token = serializers.CharField(read_only=True)
    
        def create(self, data):
            user = User.objects.create(**data)
            #数据库里密码的加密(固定的步骤)
            user.set_password(data.get('password'))
            user.save()
    
            # 补充生成记录登录状态的token  固定的格式,用过来生成jwt的token
            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)
    
            #把token发放在user里返回
            user.token = token
            return user
    
        def update(self, instance, validated_data):
            pass
    serializers.py
    from django.db import models
    from django.contrib.auth.models import AbstractUser
    # Create your models here.
    
    class User(AbstractUser):
        username = models.CharField(max_length=64, unique=True)
        password = models.CharField(max_length=255)
        phone = models.CharField(max_length=64)
        pic = models.CharField(max_length=512)
        token = models.CharField(max_length=255)
    
    
    class WbUser(models.Model):
        user_app=(
            (1,"微信"),
            (2,"微博"),
            (3,"qq"),
            (4,"支付宝")
        )
    
        uid= models.CharField(max_length=128,unique=True)
        users = models.ForeignKey(User,on_delete=models.SET_NULL,null=True)
        name = models.CharField(max_length=32,null=True)
        user_from = models.IntegerField(choices=user_app)
    model.py
    from django.shortcuts import render
    from rest_framework.response import Response
    from rest_framework.views import APIView
    from urllib.parse import urlencode
    from django_online import settings
    from rest_framework.permissions import IsAuthenticated,AllowAny
    import requests
    from .models import WbUser
    from rest_framework_jwt.settings import api_settings
    from .serializers import UserSerializer
    from django.db import transaction
    
    # Create your views here.
    
    
    class WBUrl(APIView):
        permission_classes = [AllowAny]
        def get(self,request):
    
            url="https://api.weibo.com/oauth2/authorize?"
    
            data={
                "client_id":settings.WEIBO_APP_KEY,
                "response_type":"code",
                'redirect_uri': settings.WEIBO_CALL_BACK
            }
    
            weibo_url = url+urlencode(data)
    
            print(weibo_url)
    
            return Response({"weibo_url":weibo_url})
    
    
    class WBCallBack(APIView):
        def get(self,request):
            code = request.query_params.get("code")
            print(code)
    
            data = {
                'client_id': settings.WEIBO_APP_KEY,
                'client_secret': settings.WEIBO_APP_SECRET,
                'grant_type': 'authorization_code',
                'code': code,
                'redirect_uri': settings.WEIBO_CALL_BACK,
            }
    
            url = 'https://api.weibo.com/oauth2/access_token'
            response = requests.post(url=url,data=data).json()
            print(response)
    
            uid = response.get('uid')
            print(uid)
    
            if not uid:  # 获取不到则为微博code错误
                return Response({'code': 201, 'error': '三方授权失败'})
            else:
                try:
                    user = WbUser.objects.get(uid=uid)
    
                except Exception as e:
                    return Response({"code":404,"msg":"first time login","uid":uid})
    
                else:
                    jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
                    jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
                    payload = jwt_payload_handler(user)  # user指的是你查询出来的用户
                    token = jwt_encode_handler(payload)
    
                    data={
                        "code": 200,
                        "token": token,
                        "msg": "login sucess",
                        "username":user.users.username,
                        "user_id":user.users.id
                    }
    
                    return Response(data,status=200)
    
    #检查参数是否齐全
    def check_params(list,data):
        for i in list:
            if i in data:
                pass
            else:
                return i
        return False
    
    class BindUser(APIView):
        def post(self,request):
            params = request.data
            check_result = check_params(["username","password","phone","u_id"],params)
    
            if check_result:
                data={
                    "code":200,
                    "msg": "%s is lost" % check_result
                }
                return Response(data,status=200)
    
    
    
            try:
                ser = UserSerializer(data=params)
                # print(ser)
                if ser.is_valid():
                    #使用事务来处理
                    with transaction.atomic():
                        #创建还原点
                        save_id = transaction.savepoint()
                        try:
                            user = ser.save()
    
                            wb_res = WbUser.objects.create(uid=params["u_id"],user_from=2,users=user)
                            # transaction.savepoint_commit(save_id)
    
    
                        except Exception as e:
                            #返回还原点再次执行
                            transaction.savepoint_rollback(save_id)
    
                        finally:
                            #执行成功,提交到数据库
                            transaction.savepoint_commit(save_id)
    
                    res_data = ser.data
                    res_data["code"]=200
                    return Response(res_data, status=200)
                else:
                    return  Response({"code":500,"msg":"failed"},status=200)
            except Exception as e:
                # raise e
                return Response({"code": 5001, "msg": "failed"},status=200)
    views.py
  • 相关阅读:
    ELK初学搭建(logstash)
    认识基本的UI资源
    C# 枚举器
    NGUI---使用脚本控制聊天系统的内容显示,输入事件交互
    NGUI----简单聊天系统一
    C# 类型、存储和变量
    C# Execl表格文件转xml文件
    网易云音乐如何从0到亿级用户整理笔记
    如何成为一名完美的传道授业解惑者
    grouping sets,cube,rollup,grouping__id,group by
  • 原文地址:https://www.cnblogs.com/ppzhang/p/12443707.html
Copyright © 2011-2022 走看看