增加tiktok登陆
This commit is contained in:
parent
032e103c28
commit
bf0e6c865a
55
src/controllers/tiktok.controller.ts
Normal file
55
src/controllers/tiktok.controller.ts
Normal 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 }
|
||||
}
|
||||
}
|
@ -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
32
src/net/NetClient.ts
Normal 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
33
src/service/tiktok.svr.ts
Normal 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',
|
||||
})
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user