Files
fastapi-best-architecture/backend/app/services/github_service.py
T
Wu Clan 3b64aeb97b Add OAuth 2.0 authorization login (#293)
* [WIP] Add OAuth 2.0 authorization login

* Add social user relationship table

* Update social user relationship table back_populates

* Add OAuth 2.0 related interface

* Automatically redirect authorization addresses

* Update OAuth2 authorization to GitHub

* Add implementation code

* fix the callback interface return

* fix typo

* fix the api return

* fix imports

* Fix logic for creating system users and social tables

* Fix user information storage

* Add OAuth2 source link

* remove unnecessary db refresh

* remove the front end docker-compose annotation
2024-03-15 13:46:43 +08:00

83 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from fast_captcha import text_captcha
from fastapi import BackgroundTasks, Request
from backend.app.common import jwt
from backend.app.common.enums import LoginLogStatusType, UserSocialType
from backend.app.common.exception.errors import AuthorizationError
from backend.app.common.redis import redis_client
from backend.app.core.conf import settings
from backend.app.crud.crud_user import user_dao
from backend.app.crud.crud_user_social import user_social_dao
from backend.app.database.db_mysql import async_db_session
from backend.app.schemas.token import GetLoginToken
from backend.app.schemas.user import RegisterUserParam
from backend.app.schemas.user_social import CreateUserSocialParam
from backend.app.services.login_log_service import LoginLogService
from backend.app.utils.timezone import timezone
class GithubService:
@staticmethod
async def add_with_login(request: Request, background_tasks: BackgroundTasks, user: dict) -> GetLoginToken | None:
async with async_db_session.begin() as db:
github_email = user['email']
if not github_email:
raise AuthorizationError(msg='授权失败,GitHub 账户未绑定邮箱')
github_id = user['id']
github_username = user['login']
github_nickname = user['name']
sys_user = await user_dao.check_email(db, github_email)
if not sys_user:
# 创建系统用户
sys_user = await user_dao.get_by_username(db, github_username)
if sys_user:
github_username = f'{github_username}{text_captcha(5)}'
sys_user = await user_dao.get_by_nickname(db, github_nickname)
if sys_user:
github_nickname = f'{github_nickname}{text_captcha(5)}'
new_sys_user = RegisterUserParam(
username=github_username, password=None, nickname=github_nickname, email=github_email
)
await user_dao.create(db, new_sys_user, social=True)
await db.flush()
sys_user = await user_dao.check_email(db, github_email)
# 绑定社交用户
user_social = await user_social_dao.get(db, sys_user.id, UserSocialType.github)
if not user_social:
new_user_social = CreateUserSocialParam(
source=UserSocialType.github, uid=str(github_id), user_id=sys_user.id
)
await user_social_dao.create(db, new_user_social)
# 创建 token
access_token, access_token_expire_time = await jwt.create_access_token(
str(sys_user.id), multi_login=sys_user.is_multi_login
)
refresh_token, refresh_token_expire_time = await jwt.create_refresh_token(
str(sys_user.id), access_token_expire_time, multi_login=sys_user.is_multi_login
)
await user_dao.update_login_time(db, sys_user.username)
await db.refresh(sys_user)
login_log = dict(
db=db,
request=request,
user=sys_user,
login_time=timezone.now(),
status=LoginLogStatusType.success.value,
msg='登录成功(OAuth2)',
)
background_tasks.add_task(LoginLogService.create, **login_log)
await redis_client.delete(f'{settings.CAPTCHA_LOGIN_REDIS_PREFIX}:{request.state.ip}')
data = GetLoginToken(
access_token=access_token,
refresh_token=refresh_token,
access_token_expire_time=access_token_expire_time,
refresh_token_expire_time=refresh_token_expire_time,
user=sys_user, # type: ignore
)
return data
github_service: GithubService = GithubService()