auth.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. from flask import Blueprint, redirect, url_for, session, request, flash
  2. from flask_login import login_user, logout_user, login_required, current_user
  3. from models import db, User
  4. import requests
  5. import os
  6. auth_bp = Blueprint('auth', __name__)
  7. DISCORD_API_BASE_URL = 'https://discord.com/api'
  8. AUTHORIZATION_BASE_URL = DISCORD_API_BASE_URL + '/oauth2/authorize'
  9. TOKEN_URL = DISCORD_API_BASE_URL + '/oauth2/token'
  10. @auth_bp.route('/login')
  11. def login():
  12. client_id = os.getenv('DISCORD_CLIENT_ID')
  13. redirect_uri = os.getenv('DISCORD_REDIRECT_URI')
  14. scope = 'identify'
  15. discord_login_url = f"{AUTHORIZATION_BASE_URL}?response_type=code&client_id={client_id}&scope={scope}&redirect_uri={redirect_uri}&prompt=consent"
  16. return redirect(discord_login_url)
  17. @auth_bp.route('/callback')
  18. def callback():
  19. code = request.args.get('code')
  20. if not code:
  21. flash("Error: No code provided.", "danger")
  22. return redirect(url_for('main.index'))
  23. data = {
  24. 'client_id': os.getenv('DISCORD_CLIENT_ID'),
  25. 'client_secret': os.getenv('DISCORD_CLIENT_SECRET'),
  26. 'grant_type': 'authorization_code',
  27. 'code': code,
  28. 'redirect_uri': os.getenv('DISCORD_REDIRECT_URI'),
  29. 'scope': 'identify'
  30. }
  31. headers = {
  32. 'Content-Type': 'application/x-www-form-urlencoded'
  33. }
  34. response = requests.post(TOKEN_URL, data=data, headers=headers)
  35. token_json = response.json()
  36. if 'access_token' not in token_json:
  37. flash("Error: Failed to retrieve access token.", "danger")
  38. return redirect(url_for('main.index'))
  39. access_token = token_json['access_token']
  40. user_headers = {
  41. 'Authorization': f"Bearer {access_token}"
  42. }
  43. user_response = requests.get(f"{DISCORD_API_BASE_URL}/users/@me", headers=user_headers)
  44. user_data = user_response.json()
  45. discord_id = user_data['id']
  46. username = user_data['username']
  47. user = User.query.filter_by(discord_id=discord_id).first()
  48. if not user:
  49. user = User(discord_id=discord_id, username=username)
  50. db.session.add(user)
  51. db.session.commit()
  52. else:
  53. user.username = username
  54. db.session.commit()
  55. login_user(user)
  56. flash(f"Logged in as {username}!", "success")
  57. return redirect(url_for('main.index'))
  58. @auth_bp.route('/logout')
  59. @login_required
  60. def logout():
  61. logout_user()
  62. flash("You have been logged out.", "info")
  63. return redirect(url_for('main.index'))