Skip to main content

Wallet Social Auth Local

集成 Social Auth 的目的

集成 Discord 认证(auth)通常涉及创建一个 OAuth 2.0 授权流程,以便用户能够通过 Discord 登录你的应用。以下是一个基本的交互流程,帮助你理解如何集成 Discord 认证:

以 Discord 为例

前提条件

  1. 注册 Discord 应用:在 Discord 开发者门户(https://discord.com/developers/applications)创建一个新的应用,并获取客户端 ID 和客户端密钥。
  2. 设置重定向 URI:在你的 Discord 应用设置中配置一个或多个重定向 URI,这些 URI 是用户授权后将被重定向到的地址。

OAuth 2.0 授权流程通常分为以下几个关键步骤:

  1. 用户访问授权端点:用户点击登录按钮,重定向到第三方系统(例如 Discord)的授权页面。在这个页面上,用户可以选择授予你的应用访问其信息的权限。

  2. 用户授权并重定向:用户在第三方系统上授权后,第三方系统会将用户重定向回你的应用,并附带一个授权码(authorization code)。

  3. 交换授权码为访问令牌:你的应用使用授权码向第三方系统的令牌端点(token endpoint)发送请求,以获取访问令牌(access token)。

  4. 使用访问令牌访问用户信息:你的应用使用访问令牌向第三方系统的资源端点(resource endpoint)发送请求,以获取用户信息或其他受保护的资源。

详细步骤

1. 用户访问授权端点

用户点击登录按钮,重定向到第三方系统的授权页面。

<a
href="https://discord.com/api/oauth2/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&scope=identify email"
>
通过 Discord 登录
</a>

2. 用户授权并重定向

用户在授权页面上同意授权后,第三方系统会将用户重定向回你配置的重定向 URI,并附带一个授权码。

https://your-redirect-uri.com/callback?code=AUTHORIZATION_CODE

3. 交换授权码为访问令牌

你的应用使用授权码向第三方系统的令牌端点发送请求,以获取访问令牌。

import requests

data = {
'client_id': 'YOUR_CLIENT_ID',
'client_secret': 'YOUR_CLIENT_SECRET',
'grant_type': 'authorization_code',
'code': 'AUTHORIZATION_CODE',
'redirect_uri': 'YOUR_REDIRECT_URI'
}

response = requests.post('https://discord.com/api/oauth2/token', data=data)
tokens = response.json()
access_token = tokens['access_token']

4. 使用访问令牌访问用户信息

使用访问令牌向第三方系统的资源端点发送请求,以获取用户信息。

headers = {
'Authorization': f'Bearer {access_token}'
}

response = requests.get('https://discord.com/api/users/@me', headers=headers)
user_info = response.json()

示例代码

以下是一个完整的示例,展示了如何实现上述步骤(使用 Flask 框架):

from flask import Flask, redirect, request, session, url_for
import requests

app = Flask(__name__)
app.secret_key = 'your_secret_key'

CLIENT_ID = 'YOUR_CLIENT_ID'
CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
REDIRECT_URI = 'YOUR_REDIRECT_URI'

@app.route('/')
def home():
return '<a href="/login">通过 Discord 登录</a>'

@app.route('/login')
def login():
return redirect(f'https://discord.com/api/oauth2/authorize?client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&response_type=code&scope=identify email')

@app.route('/callback')
def callback():
code = request.args.get('code')
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET',
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': REDIRECT_URI
}
response = requests.post('https://discord.com/api/oauth2/token', data=data)
tokens = response.json()
access_token = tokens['access_token']

headers = {
'Authorization': f'Bearer {access_token}'
}
user_response = requests.get('https://discord.com/api/users/@me', headers=headers)
user_info = user_response.json()

return f'Hello, {user_info["username"]}!'

if __name__ == '__main__':
app.run(debug=True)

通过这些步骤,你可以在你的应用中集成 Discord 认证,允许用户通过他们的 Discord 账户登录。这一流程同样适用于其他支持 OAuth 2.0 的第三方系统,只需替换相应的授权端点和资源端点 URL。

服务需要可以被外网访问

是的,要完成 OAuth 2.0 授权流程,特别是在开发和测试阶段,你的本地服务器需要能够被外网访问,以便第三方系统(例如 Discord)能够重定向用户回你的重定向 URI。

解决方案

有几种方法可以使你的本地服务器在开发期间被外网访问:

1. 使用 Ngrok

Ngrok 是一个非常流行的工具,可以将你的本地服务器暴露在一个公共 URL 上。它非常适合快速开发和测试。

安装 Ngrok

# 下载并解压 Ngrok
# 具体步骤请参考 https://ngrok.com/download

启动 Ngrok

# 将本地端口(例如 5000)暴露到外网
ngrok http 5000

Ngrok 会提供一个公共 URL,例如 https://abcd1234.ngrok.io,你可以将其用作重定向 URI。

2. 使用本地网络穿透工具

除了 Ngrok,还有其他类似的工具,如 LocalTunnel、Serveo 等,它们也可以将本地服务器暴露在外网。

LocalTunnel 示例

# 安装 LocalTunnel
npm install -g localtunnel

# 将本地端口(例如 5000)暴露到外网
lt --port 5000

LocalTunnel 会生成一个公共 URL,例如 https://abcd1234.loca.lt,你可以将其用作重定向 URI。

3. 部署到云服务器

如果你有云服务器(例如 AWS、Google Cloud、Heroku 等),也可以将你的应用部署到这些服务器上,从而使其可以被外网访问。

配置重定向 URI

无论你选择哪种方法,确保在 Discord 开发者门户中配置正确的重定向 URI。例如,如果你使用 Ngrok,你需要将 Ngrok 提供的公共 URL 配置为重定向 URI。

示例

假设你使用 Ngrok 并获得了一个公共 URL https://abcd1234.ngrok.io,你需要在 Discord 开发者门户中配置重定向 URI 为 https://abcd1234.ngrok.io/callback

同时,在你的 Flask 应用中,确保更新 REDIRECT_URI

CLIENT_ID = 'YOUR_CLIENT_ID'
CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
REDIRECT_URI = 'https://abcd1234.ngrok.io/callback'

完整示例

结合上述配置,完整的 Flask 应用代码如下:

from flask import Flask, redirect, request, session, url_for
import requests

app = Flask(__name__)
app.secret_key = 'your_secret_key'

CLIENT_ID = 'YOUR_CLIENT_ID'
CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
REDIRECT_URI = 'https://abcd1234.ngrok.io/callback'

@app.route('/')
def home():
return '<a href="/login">通过 Discord 登录</a>'

@app.route('/login')
def login():
return redirect(f'https://discord.com/api/oauth2/authorize?client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&response_type=code&scope=identify email')

@app.route('/callback')
def callback():
code = request.args.get('code')
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': REDIRECT_URI
}
response = requests.post('https://discord.com/api/oauth2/token', data=data)
tokens = response.json()
access_token = tokens['access_token']

headers = {
'Authorization': f'Bearer {access_token}'
}
user_response = requests.get('https://discord.com/api/users/@me', headers=headers)
user_info = user_response.json()

return f'Hello, {user_info["username"]}!'

if __name__ == '__main__':
app.run(debug=True)

通过这些步骤,你可以在本地开发环境中成功测试和集成 Discord 认证。