diff --git a/src/providers/wechat.js b/src/providers/wechat.js new file mode 100644 index 0000000000..5855c4254c --- /dev/null +++ b/src/providers/wechat.js @@ -0,0 +1,30 @@ +export default function WeChat(options) { + return { + id: "wechat", + + name: "WeChat", + type: "oauth", + version: "2.0", + scope: options.scope, + params: { grant_type: "authorization_code" }, + authorizationParams: { + appid: options.clientId + }, + protection: "state", + + accessTokenUrl: "https://api.weixin.qq.com/sns/oauth2/access_token", + authorizationUrl: + "https://open.weixin.qq.com/connect/oauth2/authorize?response_type=code", + profileUrl: "https://api.weixin.qq.com/sns/userinfo", + + async profile(profile) { + return { + id: profile.openid, + nickname: profile.nickname, + avatar: profile.headimgurl + } + }, + clientId: options.clientId, + clientSecret: options.clientSecret + } +} diff --git a/src/server/lib/oauth/client.js b/src/server/lib/oauth/client.js index b7a344576b..0ad62755d3 100644 --- a/src/server/lib/oauth/client.js +++ b/src/server/lib/oauth/client.js @@ -131,6 +131,9 @@ async function getOAuth2AccessToken (code, provider, codeVerifier) { { algorithm: 'ES256', keyid: keyId } ) params.client_secret = clientSecret + } else if (provider.id === 'wechat') { + params.appid = provider.clientId || provider.appid + params.secret = provider.clientSecret; } else { params.client_secret = provider.clientSecret } @@ -232,6 +235,17 @@ async function getOAuth2 (provider, accessToken, results) { if (provider.id === 'twitch') { headers['Client-ID'] = provider.clientId } + + // WeChat has different url params design + if (provider.id === 'wechat') { + const wechatProfileURL = new URL(url) + + wechatProfileURL.searchParams.append('access_token', results.accessToken) + wechatProfileURL.searchParams.append('openid', results.openid) + + url = wechatProfileURL.href + } + accessToken = null } diff --git a/types/providers.d.ts b/types/providers.d.ts index 8a571bf6ea..252d7ba94d 100644 --- a/types/providers.d.ts +++ b/types/providers.d.ts @@ -98,6 +98,7 @@ export type OAuthProviderType = | "Twitch" | "Twitter" | "VK" + | "WeChat" | "WordPress" | "WorkOS" | "Yandex" diff --git a/www/docs/providers/wechat.md b/www/docs/providers/wechat.md new file mode 100644 index 0000000000..e991b9fe35 --- /dev/null +++ b/www/docs/providers/wechat.md @@ -0,0 +1,30 @@ +--- +id: wechat +title: WeChat +--- + +## Documentation + +https://developers.weixin.qq.com/doc/offiaccount/en/OA_Web_Apps/Wechat_webpage_authorization.html + +## Options + +The **WeChat Provider** comes with a set of default options: + +- [WeChat Provider options](https://github.com/nextauthjs/next-auth/blob/main/src/providers/wechat.js) + +You can override any of the options to suit your own use case. + +## Example + +```js +import Providers from `next-auth/providers` +... +providers: [ + Providers.WeChat({ + clientId: process.env.WECHAT_APP_ID, + clientSecret: process.env.WECHAT_APP_SECRET + }) +] +... +```