第三方登录

大致流程(以github为例)

  • 1.打开github->setting-> developer setting-> OAuth apps-> Register a new application

  • 2.填写app信息url、回调url、设置secret key

  • 3.可以把appid、secret key记录在setting中,分布式配置在redis上

  • 4.写一个访问github登录的url(访问时注意清理缓存)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    APP_ID = '0a71c910aea67cfddd46'
    REDIRECT_URI = 'http://127.0.0.1/rms/login2'
    STATE = ''
    # 可以把key放在环境变量、redis等
    SECRET_KEY = 'e7c1eb41d600b7a6d1d8409eb44bb4bf7d4afc5c'
    from django.http import HttpResponseRedirect
    from urllib.parse import urlencode, unquote
    @api_view(['get', 'post'])
    def get_login_url(request):
    if request.method == 'GET':
    url = 'https://github.com/login/oauth/authorize?'
    params = {
    'response_type':'code',
    'client_id': APP_ID,
    'redirect_url': REDIRECT_URI,
    'state': '',
    }
    return HttpResponseRedirect(url + urlencode(params))
  • 5.由于指定了回调函数,登录成功后,github带着生成的code调用我们的回调函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    import requests
    @api_view(['get', 'post'])
    def login_by_github(request):
    code = request.GET.get('code')
    state = request.GET.get('state')
    if state != STATE:
    raise Exception('state error')
    # 获取access_token
    params = {
    'code': code,
    'client_id': APP_ID,
    'client_secret': SECRET_KEY ,
    'grant_type': 'authorization_code',
    'redirect_uri': REDIRECT_URI
    }
    url = 'https://github.com/login/oauth/access_token'
    response = requests.get(url, params=params)
    data = response.content.decode('utf-8')
    access_token = data.split('&')[0].split('=')[1]
    url2 = 'https://api.github.com/user'
    headers = {'Authorization': 'token {}'.format(access_token)}
    response = requests.get(url2, headers=headers)
    data = response.content.decode('utf-8')
  • 在回调函数中访问github的接口获取access_token

    1
    2
    3
    4
    url = 'https://github.com/login/oauth/access_token'
    response = requests.get(url, params=params)
    data = response.content.decode('utf-8')
    access_token = data.split('&')[0].split('=')[1]
  • 再通过access_token获得用户的信息

    1
    2
    3
    4
    5
    6
     access_token = data.split('&')[0].split('=')[1]
    url2 = 'https://api.github.com/user'
    headers = {'Authorization': 'token {}'.format(access_token)}
    response = requests.get(url2, headers=headers)
    # data为一个字典字符串,用json.loads
    data = response.content.decode('utf-8')
  • 此处data即为用户信息,我们可以用该用户信息和我们的网站做关联

    • 比如如果已经有用户可以把data里的id绑定我们的用户
    • 没有用户则自动创建一个基础用户,用户名就用data中的用户名,还有唯一id
      (下次第三方登录就用id去数据库查询该用户)(可以建第三方用户表区别主站用户)

各个url参数解析

https://github.com/login/oauth/authorize

参数

  • client_id
    注册信息以后就会得到一个app_id

  • redirect_uri
    在登录验证接口之后会调用回调函数

  • login
    Suggests a specific account to use for signing in and authorizing the app

  • scope
    微博服务器对自己对外开放的权限需要颗粒度的控制,比如只能获取昵称头像,
    或者只能手机号等等,一般在前期部署都会定义好,告诉微博你需要申请什么
    类型的授权scope=email

  • state
    一个随机字符串,用来避免跨站请求、攻击。在这里传入后会在回调函数中以传参的形式返回
    所以在回调函数中可以验证此函数

分享到