三方登录----微博

三方登陆流程:

 

 

微博开放平台设置app和key

 

 

 

 

 

 

 

 

 

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

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

 

django代码

setting

 
  1. import os

  2.  
  3. # Build paths inside the project like this: os.path.join(BASE_DIR, ...)

  4. BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

  5.  
  6.  
  7. # Quick-start development settings - unsuitable for production

  8. # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/

  9.  
  10. # SECURITY WARNING: keep the secret key used in production secret!

  11. SECRET_KEY = 'fivz67l6ttp5jlg%$jnrinq=j72re)x-54k(q-%y^l5+(7^h6i'

  12.  
  13. # SECURITY WARNING: don't run with debug turned on in production!

  14. DEBUG = True

  15.  
  16. ALLOWED_HOSTS = []

  17.  
  18.  
  19. # Application definition

  20.  
  21. INSTALLED_APPS = [

  22. 'django.contrib.admin',

  23. 'django.contrib.auth',

  24. 'django.contrib.contenttypes',

  25. 'django.contrib.sessions',

  26. 'django.contrib.messages',

  27. 'django.contrib.staticfiles',

  28. 'appqiniu',

  29. 'rest_framework',

  30. 'corsheaders',

  31. 'rest_framework.authtoken',

  32. 'users',

  33. 'weiboapp',

  34. "redisapp"

  35. ]

  36.  
  37. MIDDLEWARE = [

  38. 'django.middleware.security.SecurityMiddleware',

  39. 'django.contrib.sessions.middleware.SessionMiddleware',

  40. 'django.middleware.common.CommonMiddleware',

  41. # 'django.middleware.csrf.CsrfViewMiddleware',

  42. 'django.contrib.auth.middleware.AuthenticationMiddleware',

  43. 'django.contrib.messages.middleware.MessageMiddleware',

  44. 'django.middleware.clickjacking.XFrameOptionsMiddleware',

  45. 'corsheaders.middleware.CorsMiddleware',

  46.  
  47. ]

  48.  
  49. ROOT_URLCONF = 'django_online.urls'

  50.  
  51. TEMPLATES = [

  52. {

  53. 'BACKEND': 'django.template.backends.django.DjangoTemplates',

  54. 'DIRS': [os.path.join(BASE_DIR, 'templates')]

  55. ,

  56. 'APP_DIRS': True,

  57. 'OPTIONS': {

  58. 'context_processors': [

  59. 'django.template.context_processors.debug',

  60. 'django.template.context_processors.request',

  61. 'django.contrib.auth.context_processors.auth',

  62. 'django.contrib.messages.context_processors.messages',

  63. ],

  64. },

  65. },

  66. ]

  67.  
  68. WSGI_APPLICATION = 'django_online.wsgi.application'

  69.  
  70.  
  71. # Database

  72. # https://docs.djangoproject.com/en/2.2/ref/settings/#databases

  73.  
  74. DATABASES = {

  75. 'default': {

  76. 'ENGINE': 'django.db.backends.mysql',

  77. 'HOST': '127.0.0.1', # 数据库主机

  78. 'PORT': 3306, # 数据库端口

  79. 'USER': 'root', # 数据库用户名

  80. 'PASSWORD': '123456', # 数据库用户密码

  81. 'NAME': 'drf1908a_ol' # 数据库名字

  82. }

  83. }

  84.  
  85.  
  86. # Password validation

  87. # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators

  88.  
  89. AUTH_PASSWORD_VALIDATORS = [

  90. {

  91. 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',

  92. },

  93. {

  94. 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',

  95. },

  96. {

  97. 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',

  98. },

  99. {

  100. 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',

  101. },

  102. ]

  103.  
  104.  
  105. # Internationalization

  106. # https://docs.djangoproject.com/en/2.2/topics/i18n/

  107.  
  108. LANGUAGE_CODE = 'en-us'

  109.  
  110. TIME_ZONE = 'UTC'

  111.  
  112. USE_I18N = True

  113.  
  114. USE_L10N = True

  115.  
  116. USE_TZ = True

  117.  
  118.  
  119. # Static files (CSS, JavaScript, Images)

  120. # https://docs.djangoproject.com/en/2.2/howto/static-files/

  121.  
  122. STATIC_URL = '/static/'

  123. CORS_ALLOW_CREDENTIALS = True

  124. CORS_ORIGIN_ALLOW_ALL = True

  125. CORS_ORIGIN_WHITELIST = ()

  126. CORS_ALLOW_METHODS = (

  127. 'DELETE',

  128. 'GET',

  129. 'OPTIONS',

  130. 'PATCH',

  131. 'POST',

  132. 'PUT',

  133. 'VIEW',

  134. )

  135.  
  136. CORS_ALLOW_HEADERS = (

  137. 'XMLHttpRequest',

  138. 'X_FILENAME',

  139. 'accept-encoding',

  140. 'authorization',

  141. 'content-type',

  142. 'dnt',

  143. 'origin',

  144. 'user-agent',

  145. 'x-csrftoken',

  146. 'x-requested-with',

  147. 'Pragma',

  148. )

  149.  
  150. SESSION_ENGINE='django.contrib.sessions.backends.cache'

  151.  
  152. REST_FRAMEWORK = {

  153. # 身份认证

  154. 'DEFAULT_AUTHENTICATION_CLASSES': (

  155. 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',

  156. 'rest_framework.authentication.SessionAuthentication',

  157. 'rest_framework.authentication.BasicAuthentication',

  158. ),

  159.  
  160. #全局配置接口权限

  161. # 'DEFAULT_PERMISSION_CLASSES': (

  162. # 'rest_framework.permissions.IsAuthenticated',

  163. # ),

  164.  
  165. }

  166.  
  167. import datetime

  168.  
  169. JWT_AUTH = {

  170. 'JWT_AUTH_HEADER_PREFIX': 'JWT',

  171. 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),

  172. 'JWT_RESPONSE_PAYLOAD_HANDLER':

  173. 'users.views.jwt_response_payload_handler', # 重新login登录返回函数

  174. }

  175.  
  176. AUTH_USER_MODEL='users.User' # 指定使用users APP中的 model的User表作为系统认证时使用表

  177.  
  178.  
  179. WEIBO_APP_KEY = '505677658'

  180. WEIBO_APP_SECRET = '5689ef360f8e25c1df8a54e8e5653cd2'

  181. WEIBO_CALL_BACK = 'http://127.0.0.1:8080/#/weibo_callback/' # 回调路由

urls.py

 
  1. from django.urls import path,re_path,include

  2. from weiboapp import views

  3. from rest_framework_jwt.views import obtain_jwt_token # 验证密码后返回token

  4.  
  5. urlpatterns = [

  6.  
  7.  
  8. path('weibourl/', views.WBUrl.as_view(), ),

  9. path('call_back/', views.WBCallBack.as_view(), ),

  10. path('bind_user/', views.BindUser.as_view(), ),

  11.  
  12.  
  13. ]

serializers

 
  1. from rest_framework_jwt.settings import api_settings

  2. from rest_framework import serializers

  3. from users.models import User

  4.  
  5. class UserSerializer(serializers.Serializer):

  6. id =serializers.IntegerField(read_only=True)

  7. username = serializers.CharField()

  8. password = serializers.CharField()

  9. phone = serializers.CharField()

  10. token = serializers.CharField(read_only=True)

  11.  
  12. def create(self, data):

  13. user = User.objects.create(**data)

  14. #数据库里密码的加密(固定的步骤)

  15. user.set_password(data.get('password'))

  16. user.save()

  17.  
  18. # 补充生成记录登录状态的token 固定的格式,用过来生成jwt的token

  19. jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER

  20. jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

  21. payload = jwt_payload_handler(user)

  22. token = jwt_encode_handler(payload)

  23.  
  24. #把token发放在user里返回

  25. user.token = token

  26. return user

  27.  
  28. def update(self, instance, validated_data):

  29. pass

model

 
  1. from django.db import models

  2. from django.contrib.auth.models import AbstractUser

  3. # Create your models here.

  4.  
  5. class User(AbstractUser):

  6. username = models.CharField(max_length=64, unique=True)

  7. password = models.CharField(max_length=255)

  8. phone = models.CharField(max_length=64)

  9. pic = models.CharField(max_length=512)

  10. token = models.CharField(max_length=255)

  11.  
  12.  
  13. class WbUser(models.Model):

  14. user_app=(

  15. (1,"微信"),

  16. (2,"微博"),

  17. (3,"qq"),

  18. (4,"支付宝")

  19. )

  20.  
  21. uid= models.CharField(max_length=128,unique=True)

  22. users = models.ForeignKey(User,on_delete=models.SET_NULL,null=True)

  23. name = models.CharField(max_length=32,null=True)

  24. user_from = models.IntegerField(choices=user_app)

views

 
  1. from django.shortcuts import render

  2. from rest_framework.response import Response

  3. from rest_framework.views import APIView

  4. from urllib.parse import urlencode

  5. from django_online import settings

  6. from rest_framework.permissions import IsAuthenticated,AllowAny

  7. import requests

  8. from .models import WbUser

  9. from rest_framework_jwt.settings import api_settings

  10. from .serializers import UserSerializer

  11. from django.db import transaction

  12.  
  13. # Create your views here.

  14.  
  15.  
  16. class WBUrl(APIView):

  17. permission_classes = [AllowAny]

  18. def get(self,request):

  19.  
  20. url="https://api.weibo.com/oauth2/authorize?"

  21.  
  22. data={

  23. "client_id":settings.WEIBO_APP_KEY,

  24. "response_type":"code",

  25. 'redirect_uri': settings.WEIBO_CALL_BACK

  26. }

  27.  
  28. weibo_url = url+urlencode(data)

  29.  
  30. print(weibo_url)

  31.  
  32. return Response({"weibo_url":weibo_url})

  33.  
  34.  
  35. class WBCallBack(APIView):

  36. def get(self,request):

  37. code = request.query_params.get("code")

  38. print(code)

  39.  
  40. data = {

  41. 'client_id': settings.WEIBO_APP_KEY,

  42. 'client_secret': settings.WEIBO_APP_SECRET,

  43. 'grant_type': 'authorization_code',

  44. 'code': code,

  45. 'redirect_uri': settings.WEIBO_CALL_BACK,

  46. }

  47.  
  48. url = 'https://api.weibo.com/oauth2/access_token'

  49. response = requests.post(url=url,data=data).json()

  50. print(response)

  51.  
  52. uid = response.get('uid')

  53. print(uid)

  54.  
  55. if not uid: # 获取不到则为微博code错误

  56. return Response({'code': 201, 'error': '三方授权失败'})

  57. else:

  58. try:

  59. user = WbUser.objects.get(uid=uid)

  60.  
  61. except Exception as e:

  62. return Response({"code":404,"msg":"first time login","uid":uid})

  63.  
  64. else:

  65. jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER

  66. jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

  67. payload = jwt_payload_handler(user) # user指的是你查询出来的用户

  68. token = jwt_encode_handler(payload)

  69.  
  70. data={

  71. "code": 200,

  72. "token": token,

  73. "msg": "login sucess",

  74. "username":user.users.username,

  75. "user_id":user.users.id

  76. }

  77.  
  78. return Response(data,status=200)

  79.  
  80. #检查参数是否齐全

  81. def check_params(list,data):

  82. for i in list:

  83. if i in data:

  84. pass

  85. else:

  86. return i

  87. return False

  88.  
  89. class BindUser(APIView):

  90. def post(self,request):

  91. params = request.data

  92. check_result = check_params(["username","password","phone","u_id"],params)

  93.  
  94. if check_result:

  95. data={

  96. "code":200,

  97. "msg": "%s is lost" % check_result

  98. }

  99. return Response(data,status=200)

  100.  
  101.  
  102.  
  103. try:

  104. ser = UserSerializer(data=params)

  105. # print(ser)

  106. if ser.is_valid():

  107. #使用事务来处理

  108. with transaction.atomic():

  109. #创建还原点

  110. save_id = transaction.savepoint()

  111. try:

  112. user = ser.save()

  113.  
  114. wb_res = WbUser.objects.create(uid=params["u_id"],user_from=2,users=user)

  115. # transaction.savepoint_commit(save_id)

  116.  
  117.  
  118. except Exception as e:

  119. #返回还原点再次执行

  120. transaction.savepoint_rollback(save_id)

  121.  
  122. finally:

  123. #执行成功,提交到数据库

  124. transaction.savepoint_commit(save_id)

  125.  
  126. res_data = ser.data

  127. res_data["code"]=200

  128. return Response(res_data, status=200)

  129. else:

  130. return Response({"code":500,"msg":"failed"},status=200)

  131. except Exception as e:

  132. # raise e

  133. return Response({"code": 5001, "msg": "failed"},status=200)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值