Feature/use jwt in web (#533)
Co-authored-by: crazywoola <li.zheng@dentsplysirona.com> Co-authored-by: StyleZhang <jasonapring2015@outlook.com>pull/545/head
parent
57de19a5ca
commit
d49ac1e4ac
@ -0,0 +1,64 @@
|
|||||||
|
# -*- coding:utf-8 -*-
|
||||||
|
import uuid
|
||||||
|
from controllers.web import api
|
||||||
|
from flask_restful import Resource
|
||||||
|
from flask import request
|
||||||
|
from werkzeug.exceptions import Unauthorized, NotFound
|
||||||
|
from models.model import Site, EndUser, App
|
||||||
|
from extensions.ext_database import db
|
||||||
|
from libs.passport import PassportService
|
||||||
|
|
||||||
|
class PassportResource(Resource):
|
||||||
|
"""Base resource for passport."""
|
||||||
|
def get(self):
|
||||||
|
app_id = request.headers.get('X-App-Code')
|
||||||
|
if app_id is None:
|
||||||
|
raise Unauthorized('X-App-Code header is missing.')
|
||||||
|
|
||||||
|
# get site from db and check if it is normal
|
||||||
|
site = db.session.query(Site).filter(
|
||||||
|
Site.code == app_id,
|
||||||
|
Site.status == 'normal'
|
||||||
|
).first()
|
||||||
|
if not site:
|
||||||
|
raise NotFound()
|
||||||
|
# get app from db and check if it is normal and enable_site
|
||||||
|
app_model = db.session.query(App).filter(App.id == site.app_id).first()
|
||||||
|
if not app_model or app_model.status != 'normal' or not app_model.enable_site:
|
||||||
|
raise NotFound()
|
||||||
|
|
||||||
|
end_user = EndUser(
|
||||||
|
tenant_id=app_model.tenant_id,
|
||||||
|
app_id=app_model.id,
|
||||||
|
type='browser',
|
||||||
|
is_anonymous=True,
|
||||||
|
session_id=generate_session_id(),
|
||||||
|
)
|
||||||
|
db.session.add(end_user)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"iss": site.app_id,
|
||||||
|
'sub': 'Web API Passport',
|
||||||
|
'app_id': site.app_id,
|
||||||
|
'end_user_id': end_user.id,
|
||||||
|
}
|
||||||
|
|
||||||
|
tk = PassportService().issue(payload)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'access_token': tk,
|
||||||
|
}
|
||||||
|
|
||||||
|
api.add_resource(PassportResource, '/passport')
|
||||||
|
|
||||||
|
def generate_session_id():
|
||||||
|
"""
|
||||||
|
Generate a unique session ID.
|
||||||
|
"""
|
||||||
|
while True:
|
||||||
|
session_id = str(uuid.uuid4())
|
||||||
|
existing_count = db.session.query(EndUser) \
|
||||||
|
.filter(EndUser.session_id == session_id).count()
|
||||||
|
if existing_count == 0:
|
||||||
|
return session_id
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
# -*- coding:utf-8 -*-
|
||||||
|
import jwt
|
||||||
|
from werkzeug.exceptions import Unauthorized
|
||||||
|
from flask import current_app
|
||||||
|
class PassportService:
|
||||||
|
def __init__(self):
|
||||||
|
self.sk = current_app.config.get('SECRET_KEY')
|
||||||
|
|
||||||
|
def issue(self, payload):
|
||||||
|
return jwt.encode(payload, self.sk, algorithm='HS256')
|
||||||
|
|
||||||
|
def verify(self, token):
|
||||||
|
try:
|
||||||
|
return jwt.decode(token, self.sk, algorithms=['HS256'])
|
||||||
|
except jwt.exceptions.InvalidSignatureError:
|
||||||
|
raise Unauthorized('Invalid token signature.')
|
||||||
|
except jwt.exceptions.DecodeError:
|
||||||
|
raise Unauthorized('Invalid token.')
|
||||||
|
except jwt.exceptions.ExpiredSignatureError:
|
||||||
|
raise Unauthorized('Token has expired.')
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
import { fetchAccessToken } from '@/service/share'
|
||||||
|
|
||||||
|
export const checkOrSetAccessToken = async () => {
|
||||||
|
const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0]
|
||||||
|
const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' })
|
||||||
|
let accessTokenJson = { [sharedToken]: '' }
|
||||||
|
try {
|
||||||
|
accessTokenJson = JSON.parse(accessToken)
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!accessTokenJson[sharedToken]) {
|
||||||
|
const res = await fetchAccessToken(sharedToken)
|
||||||
|
accessTokenJson[sharedToken] = res.access_token
|
||||||
|
localStorage.setItem('token', JSON.stringify(accessTokenJson))
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue