# FlaskDiscordAuth
### Обзор
FlaskDiscordAuth - это Python-библиотека, разработанная для упрощения интеграции аутентификации Discord OAuth2 с приложениями Flask. Она предоставляет простой способ аутентификации пользователей через Discord, получения их основной информации, управления серверами и защиты маршрутов, требующих аутентификации.
### Установка
```bash
pip install FlaskDiscordAuth
```
### Требования
- Flask
- requests
### Базовое использование
Вот простой пример использования FlaskDiscordAuth:
```python
from flask import Flask, redirect, url_for, session, request
from FlaskDiscordAuth.discord_auth import DiscordAuth
app = Flask(__name__)
app.secret_key = 'your_secret_key'
# Настройки Discord
CLIENT_ID = 'your_client_id'
CLIENT_SECRET = 'your_client_secret'
REDIRECT_URI = 'http://127.0.0.1:5000/callback'
# Инициализируем объект аутентификации Discord
discord_auth = DiscordAuth(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI)
@app.route('/')
def home():
if 'user' in session:
user = session['user']
return f"Привет, {user['username']}!"
return 'Добро пожаловать! <a href="/login">Войти через Discord</a>'
@app.route('/login')
def login():
return redirect(discord_auth.get_login_url())
@app.route('/callback')
def callback():
code = request.args.get('code')
token_data = discord_auth.get_token(code)
session['access_token'] = token_data['access_token']
session['refresh_token'] = token_data.get('refresh_token')
session['scope'] = token_data.get('scope', '')
user_info = discord_auth.get_user_info(session['access_token'])
session['user'] = user_info
return redirect(url_for('home'))
@app.route('/logout')
def logout():
access_token = session.get('access_token')
if access_token:
discord_auth.revoke_token(access_token)
session.clear()
return redirect(url_for('home'))
if __name__ == '__main__':
app.run(debug=True)
```
### Защита маршрутов
Вы можете использовать предоставленные декораторы для защиты маршрутов:
```python
@app.route('/profile')
@discord_auth.login_required
def profile():
user = session['user']
return f"Профиль пользователя {user['username']}"
@app.route('/moderator')
@discord_auth.guilds_required('1234567890', '0987654321')
def moderator_panel():
return "Панель модератора"
```
### Расширенные возможности
#### Получение серверов пользователя
```python
@app.route('/guilds')
@discord_auth.login_required
def user_guilds():
access_token = session.get('access_token')
guilds = discord_auth.get_user_guilds(access_token)
return f"Вы состоите в {len(guilds)} серверах"
```
#### Динамические scopes
```python
@app.route('/login_with_guilds')
def login_with_guilds():
return redirect(discord_auth.get_login_url(scope='identify email guilds'))
```
#### Обновление токена
```python
refresh_token = session.get('refresh_token')
if refresh_token:
new_tokens = discord_auth.refresh_token(refresh_token)
session['access_token'] = new_tokens['access_token']
session['refresh_token'] = new_tokens['refresh_token']
```
#### Получение баннера и аватара пользователя
Библиотека теперь поддерживает получение дополнительной информации о пользователе, включая баннер:
```python
user_info = discord_auth.get_user_info(access_token)
banner_url = f"https://cdn.discordapp.com/banners/{user_info['id']}/{user_info['banner']}.png" if user_info.get('banner') else None
avatar_url = f"https://cdn.discordapp.com/avatars/{user_info['id']}/{user_info['avatar']}.png" if user_info.get('avatar') else None
```
#### Сохранение scope
Библиотека автоматически сохраняет scope в сессии, что позволяет проверять доступные разрешения:
```python
# Проверка наличия scope guilds
has_guilds_scope = 'guilds' in session.get('scope', '')
```
#### Улучшенная обработка ошибок
Декоратор `guilds_required` автоматически загружает информацию о серверах пользователя, если она отсутствует в сессии.
Raw data
{
"_id": null,
"home_page": null,
"name": "FlaskDiscordAuth",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": "authentication, discord, flask, oauth2",
"author": null,
"author_email": "fakelag28 <fakelag712@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/1c/c9/063a9cb51128410bbc38b4a5113219618a3eed870755f03549d6b002ac93/flaskdiscordauth-0.2.0.tar.gz",
"platform": null,
"description": "# FlaskDiscordAuth\n\n### \u041e\u0431\u0437\u043e\u0440\n\nFlaskDiscordAuth - \u044d\u0442\u043e Python-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 Discord OAuth2 \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438 Flask. \u041e\u043d\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 Discord, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u0445 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u043c\u0438 \u0438 \u0437\u0430\u0449\u0438\u0442\u044b \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0445 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.\n\n### \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430\n\n```bash\npip install FlaskDiscordAuth\n```\n\n### \u0422\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\n\n- Flask\n- requests\n\n### \u0411\u0430\u0437\u043e\u0432\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\n\n\u0412\u043e\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f FlaskDiscordAuth:\n\n```python\nfrom flask import Flask, redirect, url_for, session, request\nfrom FlaskDiscordAuth.discord_auth import DiscordAuth\n\napp = Flask(__name__)\napp.secret_key = 'your_secret_key'\n\n# \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 Discord\nCLIENT_ID = 'your_client_id'\nCLIENT_SECRET = 'your_client_secret'\nREDIRECT_URI = 'http://127.0.0.1:5000/callback'\n\n# \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 Discord\ndiscord_auth = DiscordAuth(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI)\n\n@app.route('/')\ndef home():\n if 'user' in session:\n user = session['user']\n return f\"\u041f\u0440\u0438\u0432\u0435\u0442, {user['username']}!\"\n return '\u0414\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c! <a href=\"/login\">\u0412\u043e\u0439\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 Discord</a>'\n\n@app.route('/login')\ndef login():\n return redirect(discord_auth.get_login_url())\n\n@app.route('/callback')\ndef callback():\n code = request.args.get('code')\n token_data = discord_auth.get_token(code)\n session['access_token'] = token_data['access_token']\n session['refresh_token'] = token_data.get('refresh_token')\n session['scope'] = token_data.get('scope', '')\n user_info = discord_auth.get_user_info(session['access_token'])\n session['user'] = user_info\n return redirect(url_for('home'))\n\n@app.route('/logout')\ndef logout():\n access_token = session.get('access_token')\n if access_token:\n discord_auth.revoke_token(access_token)\n session.clear()\n return redirect(url_for('home'))\n\nif __name__ == '__main__':\n app.run(debug=True)\n```\n\n### \u0417\u0430\u0449\u0438\u0442\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432\n\n\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b \u0434\u043b\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432:\n\n```python\n@app.route('/profile')\n@discord_auth.login_required\ndef profile():\n user = session['user']\n return f\"\u041f\u0440\u043e\u0444\u0438\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f {user['username']}\"\n\n@app.route('/moderator')\n@discord_auth.guilds_required('1234567890', '0987654321')\ndef moderator_panel():\n return \"\u041f\u0430\u043d\u0435\u043b\u044c \u043c\u043e\u0434\u0435\u0440\u0430\u0442\u043e\u0440\u0430\"\n```\n\n### \u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438\n\n#### \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\n\n```python\n@app.route('/guilds')\n@discord_auth.login_required\ndef user_guilds():\n access_token = session.get('access_token')\n guilds = discord_auth.get_user_guilds(access_token)\n return f\"\u0412\u044b \u0441\u043e\u0441\u0442\u043e\u0438\u0442\u0435 \u0432 {len(guilds)} \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u0445\"\n```\n\n#### \u0414\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0435 scopes\n\n```python\n@app.route('/login_with_guilds')\ndef login_with_guilds():\n return redirect(discord_auth.get_login_url(scope='identify email guilds'))\n```\n\n#### \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u0430\n\n```python\nrefresh_token = session.get('refresh_token')\nif refresh_token:\n new_tokens = discord_auth.refresh_token(refresh_token)\n session['access_token'] = new_tokens['access_token']\n session['refresh_token'] = new_tokens['refresh_token']\n```\n\n#### \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0431\u0430\u043d\u043d\u0435\u0440\u0430 \u0438 \u0430\u0432\u0430\u0442\u0430\u0440\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\n\n\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0431\u0430\u043d\u043d\u0435\u0440:\n\n```python\nuser_info = discord_auth.get_user_info(access_token)\nbanner_url = f\"https://cdn.discordapp.com/banners/{user_info['id']}/{user_info['banner']}.png\" if user_info.get('banner') else None\navatar_url = f\"https://cdn.discordapp.com/avatars/{user_info['id']}/{user_info['avatar']}.png\" if user_info.get('avatar') else None\n```\n\n#### \u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 scope\n\n\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 scope \u0432 \u0441\u0435\u0441\u0441\u0438\u0438, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f:\n\n```python\n# \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u044f scope guilds\nhas_guilds_scope = 'guilds' in session.get('scope', '')\n```\n\n#### \u0423\u043b\u0443\u0447\u0448\u0435\u043d\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a\n\n\u0414\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 `guilds_required` \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u0441\u0435\u0441\u0441\u0438\u0438.",
"bugtrack_url": null,
"license": null,
"summary": "A Python library to simplify Discord OAuth2 authentication with Flask applications",
"version": "0.2.0",
"project_urls": {
"Homepage": "https://github.com/fakelag28/flask-discord-auth",
"Source": "https://github.com/fakelag28/flask-discord-auth"
},
"split_keywords": [
"authentication",
" discord",
" flask",
" oauth2"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "8861c7ec07a8fb84ee7016829f80d641d72bc0b405a2149961dfc50bfea8fb20",
"md5": "31b211198a76a18b23306b9d212316e6",
"sha256": "652d3c706d16e268a47f00cf2886f908d80fa93314b55bf6bf2ac31be418a9b7"
},
"downloads": -1,
"filename": "flaskdiscordauth-0.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "31b211198a76a18b23306b9d212316e6",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 5282,
"upload_time": "2025-08-23T17:13:31",
"upload_time_iso_8601": "2025-08-23T17:13:31.827855Z",
"url": "https://files.pythonhosted.org/packages/88/61/c7ec07a8fb84ee7016829f80d641d72bc0b405a2149961dfc50bfea8fb20/flaskdiscordauth-0.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "1cc9063a9cb51128410bbc38b4a5113219618a3eed870755f03549d6b002ac93",
"md5": "67b8d1dc220935bc74d74c8a5d322a14",
"sha256": "2a87aa3b92cfab08b03e5be9a129d4210752d23b1ca877a92aab069852f226ab"
},
"downloads": -1,
"filename": "flaskdiscordauth-0.2.0.tar.gz",
"has_sig": false,
"md5_digest": "67b8d1dc220935bc74d74c8a5d322a14",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 8194,
"upload_time": "2025-08-23T17:13:32",
"upload_time_iso_8601": "2025-08-23T17:13:32.839809Z",
"url": "https://files.pythonhosted.org/packages/1c/c9/063a9cb51128410bbc38b4a5113219618a3eed870755f03549d6b002ac93/flaskdiscordauth-0.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-23 17:13:32",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "fakelag28",
"github_project": "flask-discord-auth",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "requests",
"specs": []
},
{
"name": "Flask",
"specs": []
}
],
"lcname": "flaskdiscordauth"
}