优化twitter oauth流程
This commit is contained in:
parent
f039e796e5
commit
7fd65ba0bb
@ -4,6 +4,7 @@ import { role, router } from 'decorators/router'
|
|||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
import { AuthRecord } from 'modules/AuthRecord'
|
import { AuthRecord } from 'modules/AuthRecord'
|
||||||
import { DiscordSvr, exchangeDiscrodCodeForToken, userInfo } from 'services/discord.svr'
|
import { DiscordSvr, exchangeDiscrodCodeForToken, userInfo } from 'services/discord.svr'
|
||||||
|
import { parseOauthState } from 'utils/net.util'
|
||||||
|
|
||||||
class DiscordController extends BaseController {
|
class DiscordController extends BaseController {
|
||||||
@role(ROLE_ANON)
|
@role(ROLE_ANON)
|
||||||
@ -11,7 +12,7 @@ class DiscordController extends BaseController {
|
|||||||
async discordCallback(req, res) {
|
async discordCallback(req, res) {
|
||||||
let { code, state } = req.params
|
let { code, state } = req.params
|
||||||
if (code && state) {
|
if (code && state) {
|
||||||
const stateArr = state.split('|')
|
const stateArr = parseOauthState(state)
|
||||||
const address = stateArr[0].toLowerCase()
|
const address = stateArr[0].toLowerCase()
|
||||||
const record = await AuthRecord.insertOrUpdate(
|
const record = await AuthRecord.insertOrUpdate(
|
||||||
{ address, platform: 7 },
|
{ address, platform: 7 },
|
||||||
@ -22,17 +23,26 @@ class DiscordController extends BaseController {
|
|||||||
record.refreshToken = tokenResponse.refresh_token
|
record.refreshToken = tokenResponse.refresh_token
|
||||||
record.scope = tokenResponse.scope
|
record.scope = tokenResponse.scope
|
||||||
record.tokenType = tokenResponse.token_type
|
record.tokenType = tokenResponse.token_type
|
||||||
record.expiresIn = tokenResponse.expires_in + Date.now()
|
record.expiresIn = tokenResponse.expires_in || 0 + Date.now()
|
||||||
await record.save()
|
await record.save()
|
||||||
let uinfo = await userInfo(tokenResponse.access_token)
|
if (tokenResponse && tokenResponse.access_token) {
|
||||||
record.nickname = uinfo.username
|
let uinfo = await userInfo(tokenResponse.access_token)
|
||||||
record.username = uinfo.username
|
record.nickname = uinfo.username
|
||||||
record.discriminator = uinfo.discriminator
|
record.username = uinfo.username
|
||||||
record.openId = uinfo.id
|
record.discriminator = uinfo.discriminator
|
||||||
await record.save()
|
record.openId = uinfo.id
|
||||||
return res.view('/templates/discord_redirect.ejs')
|
await record.save()
|
||||||
} else {
|
}
|
||||||
return res.view('/templates/discord_redirect.ejs')
|
if (stateArr.length > 2) {
|
||||||
|
return res.redirect(stateArr[2])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (state) {
|
||||||
|
const stateArr = parseOauthState(state)
|
||||||
|
if (stateArr.length > 2) {
|
||||||
|
return res.redirect(stateArr[2])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.view('/templates/discord_redirect.ejs')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import BaseController, { ROLE_ANON } from 'common/base.controller'
|
import BaseController, { ROLE_ANON } from 'common/base.controller'
|
||||||
import { ZError } from 'common/ZError'
|
|
||||||
import { role, router } from 'decorators/router'
|
import { role, router } from 'decorators/router'
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
import { AuthRecord } from 'modules/AuthRecord'
|
import { AuthRecord } from 'modules/AuthRecord'
|
||||||
import { exchangeTwitterCodeForToken, getTwitterUserInfo } from 'services/twitter.svr'
|
import { exchangeTwitterCodeForToken, getTwitterUserInfo } from 'services/twitter.svr'
|
||||||
|
import { parseOauthState } from 'utils/net.util'
|
||||||
|
|
||||||
class TwitterController extends BaseController {
|
class TwitterController extends BaseController {
|
||||||
@role(ROLE_ANON)
|
@role(ROLE_ANON)
|
||||||
@ -12,7 +12,7 @@ class TwitterController extends BaseController {
|
|||||||
logger.info('twitter redirect: ', req.params)
|
logger.info('twitter redirect: ', req.params)
|
||||||
const { code, state } = req.params
|
const { code, state } = req.params
|
||||||
if (code && state) {
|
if (code && state) {
|
||||||
const stateArr = state.split('|')
|
const stateArr = parseOauthState(state)
|
||||||
const address = stateArr[0].toLowerCase()
|
const address = stateArr[0].toLowerCase()
|
||||||
const record = await AuthRecord.insertOrUpdate(
|
const record = await AuthRecord.insertOrUpdate(
|
||||||
{ address, platform: 4 },
|
{ address, platform: 4 },
|
||||||
@ -24,13 +24,24 @@ class TwitterController extends BaseController {
|
|||||||
record.refreshToken = tokenResponse.refresh_token
|
record.refreshToken = tokenResponse.refresh_token
|
||||||
record.scope = tokenResponse.scope
|
record.scope = tokenResponse.scope
|
||||||
record.tokenType = tokenResponse.token_type
|
record.tokenType = tokenResponse.token_type
|
||||||
record.expiresIn = tokenResponse.expires_in + Date.now()
|
record.expiresIn = tokenResponse.expires_in || 0 + Date.now()
|
||||||
await record.save()
|
|
||||||
const uinfo = await getTwitterUserInfo(tokenResponse.access_token)
|
|
||||||
record.nickname = uinfo.data.name
|
|
||||||
record.username = uinfo.data.username
|
|
||||||
record.openId = uinfo.data.id
|
|
||||||
await record.save()
|
await record.save()
|
||||||
|
if (tokenResponse && tokenResponse.access_token) {
|
||||||
|
const uinfo = await getTwitterUserInfo(tokenResponse.access_token)
|
||||||
|
record.nickname = uinfo.data.name
|
||||||
|
record.username = uinfo.data.username
|
||||||
|
record.openId = uinfo.data.id
|
||||||
|
await record.save()
|
||||||
|
}
|
||||||
|
if (stateArr.length > 2) {
|
||||||
|
return res.redirect(stateArr[2])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state) {
|
||||||
|
const stateArr = parseOauthState(state)
|
||||||
|
if (stateArr.length > 2) {
|
||||||
|
return res.redirect(stateArr[2])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return res.view('/templates/twitter_redirect.ejs')
|
return res.view('/templates/twitter_redirect.ejs')
|
||||||
}
|
}
|
||||||
|
@ -128,38 +128,38 @@ export function generateKVStr({
|
|||||||
sort = false,
|
sort = false,
|
||||||
encode = false,
|
encode = false,
|
||||||
ignoreNull = true,
|
ignoreNull = true,
|
||||||
splitChar = "&",
|
splitChar = '&',
|
||||||
equalChar = "=",
|
equalChar = '=',
|
||||||
uri = "",
|
uri = '',
|
||||||
}: {
|
}: {
|
||||||
data?: any;
|
data?: any
|
||||||
sort?: boolean;
|
sort?: boolean
|
||||||
encode?: boolean;
|
encode?: boolean
|
||||||
ignoreNull?: boolean;
|
ignoreNull?: boolean
|
||||||
splitChar?: string;
|
splitChar?: string
|
||||||
equalChar?: string;
|
equalChar?: string
|
||||||
uri?: string;
|
uri?: string
|
||||||
}) {
|
}) {
|
||||||
const keys = Object.keys(data);
|
const keys = Object.keys(data)
|
||||||
sort && keys.sort();
|
sort && keys.sort()
|
||||||
let result = "";
|
let result = ''
|
||||||
let i = 0;
|
let i = 0
|
||||||
for (let key of keys) {
|
for (let key of keys) {
|
||||||
if (ignoreNull && !data[key]) {
|
if (ignoreNull && !data[key]) {
|
||||||
continue;
|
continue
|
||||||
}
|
}
|
||||||
if (i++ > 0) result += splitChar;
|
if (i++ > 0) result += splitChar
|
||||||
if (encode) {
|
if (encode) {
|
||||||
result += `${key}${equalChar}${encodeURIComponent(data[key])}`;
|
result += `${key}${equalChar}${encodeURIComponent(data[key])}`
|
||||||
} else {
|
} else {
|
||||||
result += `${key}${equalChar}${data[key]}`;
|
result += `${key}${equalChar}${data[key]}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (uri) {
|
if (uri) {
|
||||||
const joinChar = uri.search(/\?/) === -1 ? "?" : "&";
|
const joinChar = uri.search(/\?/) === -1 ? '?' : '&'
|
||||||
result = uri + joinChar + result;
|
result = uri + joinChar + result
|
||||||
}
|
}
|
||||||
return result;
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,19 +168,23 @@ export function generateKVStr({
|
|||||||
* @param splitChar 连接的字符, 默认是&
|
* @param splitChar 连接的字符, 默认是&
|
||||||
* @param equalChar =
|
* @param equalChar =
|
||||||
*/
|
*/
|
||||||
export function keyValToObject(
|
export function keyValToObject(str: string, splitChar: string = '&', equalChar = '='): {} {
|
||||||
str: string,
|
let result: any = {}
|
||||||
splitChar: string = "&",
|
|
||||||
equalChar = "="
|
|
||||||
): {} {
|
|
||||||
let result: any = {};
|
|
||||||
if (!str) {
|
if (!str) {
|
||||||
return result;
|
return result
|
||||||
}
|
}
|
||||||
let arrs = str.split(splitChar);
|
let arrs = str.split(splitChar)
|
||||||
for (let sub of arrs) {
|
for (let sub of arrs) {
|
||||||
let subArr = sub.split(equalChar);
|
let subArr = sub.split(equalChar)
|
||||||
result[subArr[0]] = subArr[1];
|
result[subArr[0]] = subArr[1]
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseOauthState(state: string) {
|
||||||
|
if (state.startsWith('0x')) {
|
||||||
|
return state.split('|')
|
||||||
|
} else {
|
||||||
|
return atob(state).split('|')
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
<body>
|
<body>
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
|
// const bc = new BroadcastChannel("cebg")
|
||||||
|
// bc.postMessage("twitter login finished")
|
||||||
window.close();
|
window.close();
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user