增加tiktok登陆

This commit is contained in:
cebgcontract 2022-12-08 16:43:58 +08:00
parent 032e103c28
commit bf0e6c865a
4 changed files with 131 additions and 0 deletions

View File

@ -0,0 +1,55 @@
import BaseController from 'common/base.controller'
import { ZError } from 'common/ZError'
import { role, router } from 'decorators/router'
import { Account, PlatEnum } from 'modules/Account'
import { fetchAccessToken, refreshAccessToken } from 'service/tiktok.svr'
// 在tiktok的过期时间中, 减少一个小时
const EXPIRE_REDUCE_SECOND = 3600
class TiktokController extends BaseController {
@role('anon')
@router('post /wallet/login/tiktok')
async checkTiktokCode(req, res) {
let { code } = req.params
let result = await fetchAccessToken(code)
console.log(result)
if (!(result.message === 'success' && result.data?.error_code === 0)) {
throw new ZError(10, `${result.message}: ${result.data?.description} (${result.data?.error_code})`)
}
const openId = result.data['open_id']
let user: any = {}
let now = Date.now() / 1000
user.accessToken = result.data['access_token']
user.refreshToken = result.data['refresh_token']
user.accessTokenExpire = now + result.data['expires_in'] - EXPIRE_REDUCE_SECOND
user.refreshTokenExpire = now + result.data['refresh_expires_in'] - EXPIRE_REDUCE_SECOND
user.scope = result.data['scope']
let account = await Account.insertOrUpdate({ plat: PlatEnum.TIKTOK, openId }, user)
const ztoken = await res.jwtSign({ id: account.id })
return { token: ztoken }
}
@router('post /wallet/tiktok/accesstoken')
async getTiktokAccessToken(req, res) {
let user = req.user
let now = Date.now() / 1000
if (user.accessToken && user.accessTokenExpire) {
if (now < user.accessTokenExpire) {
return { accessToken: user.accessToken }
}
}
if (user.refreshToken && user.refreshTokenExpire) {
if (now >= user.accessTokenExpire) {
throw new ZError(11, 'need login again')
}
}
let result = await refreshAccessToken(user.refreshToken)
if (!(result.message === 'success' && result.data?.error_code === 0)) {
throw new ZError(10, `${result.message}: ${result.data?.description} (${result.data?.error_code})`)
}
user.accessToken = result.data['access_token']
user.refreshToken = result.data['refresh_token']
user.accessTokenExpire = now + result.data['expires_in'] - EXPIRE_REDUCE_SECOND
user.refreshTokenExpire = now + result.data['refresh_expires_in'] - EXPIRE_REDUCE_SECOND
await user.save()
return { accessToken: user.accessToken }
}
}

View File

@ -6,6 +6,7 @@ import { BaseModule } from './Base'
export enum PlatEnum {
GOOGLE = 0,
APPLE = 1,
TIKTOK = 2,
}
interface AccountClass extends Base, TimeStamps {}
@ -37,6 +38,16 @@ class AccountClass extends BaseModule {
public comment?: string
@prop()
public lastLogin?: Date
@prop()
public accessToken?: string
@prop()
public accessTokenExpire?: number
@prop()
public refreshToken?: string
@prop()
public refreshTokenExpire?: number
@prop()
public scope?: string
}
export const Account = getModelForClass(AccountClass, { existingConnection: AccountClass.db })

32
src/net/NetClient.ts Normal file
View File

@ -0,0 +1,32 @@
import axios, { AxiosRequestConfig } from 'axios'
export interface IReqData {
url: string
method?: string
data?: any
}
export class NetClient {
httpGet(reqData: IReqData | string): Promise<any> {
let opt: AxiosRequestConfig = { method: 'get' }
if (typeof reqData == 'string') {
opt.url = reqData
} else {
Object.assign(opt, reqData)
}
return this.request(opt)
}
httpPost(data: IReqData): Promise<any> {
let reqData: AxiosRequestConfig = {
method: 'post',
}
Object.assign(reqData, data)
return this.request(reqData)
}
request(data: AxiosRequestConfig): Promise<any> {
let defaultCfg: AxiosRequestConfig = {
method: 'get',
}
Object.assign(defaultCfg, data)
return axios(defaultCfg).then(res => res.data)
}
}

33
src/service/tiktok.svr.ts Normal file
View File

@ -0,0 +1,33 @@
import { NetClient } from 'net/NetClient'
const TIKTOK_ACCESS_TOKEN_URL = 'https://open-api.tiktok.com/oauth/access_token/'
const TIKTOK_REFRESH_TOKEN_URL = 'https://open-api.tiktok.com/oauth/refresh_token/'
const TIKTOK_REVOKE_ACCESS_URL = 'https://open-api.tiktok.com/oauth/revoke/'
const CLIENT_KEY = 'awqbuzh2qymmq8hs'
const CLIENT_SECRET = '12f6e52173e825fa04ff2c7d4480e28b'
export function fetchAccessToken(code: string) {
let url_access_token = TIKTOK_ACCESS_TOKEN_URL
url_access_token += '?client_key=' + CLIENT_KEY
url_access_token += '&client_secret=' + CLIENT_SECRET
url_access_token += '&code=' + code
url_access_token += '&grant_type=authorization_code'
return new NetClient().httpPost({
url: url_access_token,
method: 'post',
})
}
export function refreshAccessToken(refresh_token: string) {
let url_refresh_token = TIKTOK_REFRESH_TOKEN_URL
url_refresh_token += '?client_key=' + CLIENT_KEY
url_refresh_token += '&grant_type=refresh_token'
url_refresh_token += '&refresh_token=' + refresh_token
return new NetClient().httpPost({
url: url_refresh_token,
method: 'post',
})
}