libushang 6 місяців тому
батько
коміт
3914d0aafa
4 змінених файлів з 128 додано та 50 видалено
  1. 8 4
      .env
  2. 17 8
      config.py
  3. 81 3
      routers/prod_api/auth.py
  4. 22 35
      routers/prod_api/zwrz.py

+ 8 - 4
.env

@@ -30,8 +30,10 @@ STAGE_MYSQL_DB_NAME = 'mmyjhd'
 STAGE_MYSQL_PORT = '3306'
 
 # 粤政易
-STAGE_YZY_PASS_ID = 'zwrz_mmzhyj'
-STAGE_YZY_PASS_TOKEN = '8e19726304CD4318laex'
+
+# 统一身份认证(粤政易)
+STAGE_TYRZ_CLIENT_ID = 'zwrz_mmzhyj'
+STAGE_TYRZ_CLIENT_SECRET = '8e19726304CD4318laex'
 
 # 中屏后台管理地址
 STAGE_YJHTGL_WEB_ROOT_PATH = "http://19.155.220.206:8086/yjzp/#"
@@ -53,5 +55,7 @@ PROD_MYSQL_DB_NAME = 'mmyjhd'
 PROD_MYSQL_PORT = '3306'
 
 # 粤政易
-PROD_YZY_PASS_ID = 'zwrz_mmzhyj'
-PROD_YZY_PASS_TOKEN = '8e19726304CD4318laex'
+
+# 统一身份认证(粤政易)
+PROD_TYRZ_CLIENT_ID = 'zwrz_mmzhyj'
+PROD_TYRZ_CLIENT_SECRET = '-------------'

+ 17 - 8
config.py

@@ -86,10 +86,10 @@ class ProdConfig(Settings):
     YJXP_CALLBACK_WEB_PATH: Optional[str] = Field(..., env="PROD_YJXP_CALLBACK_WEB_PATH")
 
     # 粤政易
-    YZY_PASS_ID: Optional[str] = Field(..., env="PROD_YZY_PASS_ID")
-    YZY_PASS_TOKEN: Optional[str] = Field(..., env="PROD_YZY_PASS_TOKEN")
-    YZY_HOST = "https://xtbg.digitalgd.com.cn"
-    YZY_API_ROOT = "http://19.15.0.128:8080"
+    # YZY_PASS_ID: Optional[str] = Field(..., env="PROD_YZY_PASS_ID")
+    # YZY_PASS_TOKEN: Optional[str] = Field(..., env="PROD_YZY_PASS_TOKEN")
+    # YZY_HOST = "https://xtbg.digitalgd.com.cn"
+    # YZY_API_ROOT = "http://19.15.0.128:8080"
 
     REDIS_DB_URL = {
         'host': '127.0.0.1',
@@ -115,10 +115,19 @@ class StageConfig(Settings):
     YJXP_CALLBACK_WEB_PATH: Optional[str] = Field(..., env="STAGE_YJXP_CALLBACK_WEB_PATH")
 
     # 粤政易
-    YZY_PASS_ID: Optional[str] = Field(..., env="STAGE_YZY_PASS_ID")
-    YZY_PASS_TOKEN: Optional[str] = Field(..., env="STAGE_YZY_PASS_TOKEN")
-    YZY_HOST = "https://xtbg.digitalgd.com.cn"
-    YZY_API_ROOT = "http://19.15.0.128:8080"
+    # YZY_PASS_ID: Optional[str] = Field(..., env="STAGE_YZY_PASS_ID")
+    # YZY_PASS_TOKEN: Optional[str] = Field(..., env="STAGE_YZY_PASS_TOKEN")
+    # YZY_HOST = "https://xtbg.digitalgd.com.cn"
+    # YZY_API_ROOT = "http://19.15.0.128:8080"
+
+    # 统一认证登录
+    HOME_URL = "http://19.155.220.206:8086"
+    TYRZ_CLIENT_ID: Optional[str] = Field(..., env="STAGE_TYRZ_CLIENT_ID")
+    TYRZ_CLIENT_SECRET: Optional[str] = Field(..., env="STAGE_TYRZ_CLIENT_SECRET")
+    TYRZ_REDIRECT_URI = "http://19.155.220.206:8086/tyrz/login"
+    TYRZ_GET_TOKEN = 'https://xtbg.digitalgd.com.cn/zwrz/rz/sso/oauth/token'
+    TYRZ_GET_TOKEN_INFO = 'https://xtbg.digitalgd.com.cn/zwrz/rz/sso/openapi/user/getuserinfo'
+    TYRZ_LOGOUT = 'https://xtbg.digitalgd.com.cn/zwrz/rz/sso/logout?client_id={}&backurl='
 
     REDIS_DB_URL = {
         'host': '127.0.0.1',

+ 81 - 3
routers/prod_api/auth.py

@@ -17,6 +17,8 @@ from common.security import valid_access_token
 from common.auth_user import *
 from common import YzyApi
 from models import *
+from urllib.parse import quote
+import requests
 
 router = APIRouter()
 
@@ -201,13 +203,23 @@ async def login(
 async def logout(
     request: Request, 
     db: Session = Depends(get_db),
-    client_id: str = Depends(valid_access_token)
+    user: AuthUser = Depends(get_auth_user)
 ):
+    logger.info("logout ok")
+    request.session.clear()
+    
+    if user.is_yzy_user == 1:
+        logout_url = settings.TYRZ_LOGOUT.format(settings.TYRZ_CLIENT_ID) + quote(settings.HOME_URL+"/yjzp/")
+        logger.info(logout_url)
+    else:
+        logout_url = settings.HOME_URL+"/yjzp/"
     return {
         "code": 200,
-        "msg": "退出成功"
+        "msg": "退出成功",
+        "data": logout_url
     }
 
+# 小屏专用
 @router.post('/yzy/callback')
 async def yzy(
     request: Request, 
@@ -272,4 +284,70 @@ async def yzy(
             "scope": "",
             "redirect_url": state_json['redirect_url']
         }
-    }
+    }
+
+# 粤政易token登录
+@router.post('/yzylogin')
+async def login(
+    request: Request,
+    data: dict = Depends(remove_xss_json),
+    db: Session = Depends(get_db)
+):
+    code = data['code']
+    redis_key = "yzy_" + code
+    user_id = redis_get(redis_key)
+    if user_id is None:
+        return {
+            "code": 500,
+            "msg": "用户不是本系统用户"
+        }
+
+    row = db.query(SysUser).filter(SysUser.user_id == int(user_id)).first()
+    if row is None:
+        return {
+            "code": 500,
+            "msg": "用户不是本系统用户"
+        }
+    
+    user_id = str(row.user_id)
+
+    auth = {
+        "user_id": user_id,
+        "user_name": row.user_name,  
+        "nick_name": row.nick_name,
+        "is_yzy_user": "1"
+    }
+
+    request.session['user_auth'] = auth
+    request.session['user_auth_sign'] = data_auth_sign(auth)
+    request.session['user_name'] = row.user_name
+
+    # db_czrz_serv.log_username(db, row.uid, row.username, "登录", "后台管理账号+密码登录成功", request.client.host)
+    row.login_date = datetime.now()
+    row.login_ip = request.client.host
+    # row.login = row.login + 1
+    db.commit()
+
+    access_token_expires = timedelta(seconds = 7200)
+    access_token = security.create_access_token(
+        data={"sub": user_id}, expires_delta = access_token_expires
+    )
+
+    refresh_token_expires = timedelta(seconds = 7200)
+    refresh_token = security.create_access_token(
+        data={"sub": user_id}, expires_delta = refresh_token_expires
+    )
+
+    return {
+        "code": 200,
+        "msg": "操作成功",
+        "data": {
+            "access_token": access_token,
+            "refresh_token": refresh_token,
+            "expire_in": 7200,
+            "refresh_expire_in": 7200,
+            "client_id": 0,
+            "scope": "",
+            "openid": ""
+        }
+    }

+ 22 - 35
routers/prod_api/zwrz.py

@@ -1,6 +1,6 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
-from fastapi import APIRouter, Depends
+from fastapi import APIRouter, Depends, Query
 from fastapi import Request
 from fastapi.responses import RedirectResponse, PlainTextResponse
 from sqlalchemy.orm import Session
@@ -19,6 +19,7 @@ from urllib.parse import quote
 from utils import *
 from utils.redis_util import *
 from datetime import timedelta
+import traceback
 
 router = APIRouter()
 
@@ -27,9 +28,10 @@ async def login(
     *,
     request: Request,
     code: str,
+    redirect: str = Query(None),
     db: Session = Depends(get_db) 
 ):
-    logger.info("统一认证登录 code: {}", code)
+    logger.info("统一认证登录 code: {}, redirect: {}", code, redirect)
 
     print(request.client.host)
     
@@ -55,9 +57,9 @@ async def login(
             "code": code,
             "client_secret": settings.TYRZ_CLIENT_SECRET
         }
-        print('data', data)
+        print('data:', data)
         response = requests.post(get_token_url, data=data, headers=headers, timeout=15)
-        print(response.text)
+        print("统一身份证 response:", response.text)
         if response.status_code == 200 :
             result = response.json()
             status = int(result['status'])
@@ -81,48 +83,33 @@ async def login(
             status = int(result['status'])
             if status == 0:
                 data = result['data']
+                userId = data['userId'] # 用户粤政易ID
                 mobile = data['mobile']
                 name = data['name']
                 sfzh = data['certificateNumber']
+                #units = data['units']
+                #if len(units) > 0:
+                #    unitPath = units['0']['unitPath']
             else:
                 message = result['message']
                 return PlainTextResponse("统一身份证失败,原因:"+message)
     except Exception as e:
+        traceback.print_exc()
         return PlainTextResponse("统一身份证超时,请稍后再试。")
     
-    row = db.query(SysUser).filter_by(SysUser.yzy_account == mobile).first()
+    row = db.query(SysUser).filter(SysUser.yzy_account == mobile).first()
     if row is None:
         logger.error("没有匹配的账号绑定用户。")
         user = {"username": name, "mobile": mobile}
-        return {}
-
-    user_id = str(row.user_id)
-
-    auth = {
-        "user_id": user_id,
-        "user_name": row.user_name,  
-        "nick_name": row.nick_name,
-        "is_yzy_user": "1"
-    }
-
-    request.session['user_auth'] = auth
-    request.session['user_auth_sign'] = data_auth_sign(auth)
-    request.session['user_name'] = row.user_name
-
-    # db_czrz_serv.log_username(db, row.uid, row.username, "登录", "后台管理账号+密码登录成功", request.client.host)
-    row.login_date = datetime.now()
-    row.login_ip = request.client.host
-    # row.login = row.login + 1
-    db.commit()
-
-    access_token_expires = timedelta(seconds = 7200)
-    access_token = security.create_access_token(
-        data={"sub": user_id}, expires_delta = access_token_expires
-    )
+        goto_url = "/yzy/#/noyzyuser"
+        return RedirectResponse(url=goto_url)
 
-    refresh_token_expires = timedelta(seconds = 7200)
-    refresh_token = security.create_access_token(
-        data={"sub": user_id}, expires_delta = refresh_token_expires
-    )
+    # 保存user_id
+    code = new_guid()
+    redis_set_with_time("yzy_" + code, str(row.user_id), 600)
 
-    return RedirectResponse(url="/yjzp/#/login?token="+access_token)
+    goto_url = "/yjzp/#/yzylogin?code=" + code
+    if redirect is not None:
+        goto_url = goto_url + "&redirect="+redirect
+    logger.info("goto_url: {}", goto_url)
+    return RedirectResponse(url=goto_url)