-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is Twitter provider working? #53
Comments
I hadn't enabled Sorry. |
Even after enabling |
I have the same issue - with OAuth v1 and v2. Did you managed to make it work? |
Would be better to write own twitter provider... I could have got this to work using twitter-api-v2 like below: export const auth: SvelteKitAuth = new SvelteKitAuth({
...
providers: [
...
new class extends TwitterAuthProvider {
constructor() {
super({
apiKey: process.env.AUTH_TWITTER_API_KEY,
apiSecret: process.env.AUTH_TWITTER_API_SECRET,
profile: (profile) => {
return { ...profile, provider: 'twitter' };
},
})
}
getRequestToken = async (auth, host): Promise<any> => {
const { url, ...oauthResult } = await (new TwitterApi({
appKey: this.config.apiKey,
appSecret: this.config.apiSecret
})).readOnly.generateAuthLink(
encodeURIComponent(this.getCallbackUri()), { authAccessType: 'read' }
);
return {
oauthToken: oauthResult.oauth_token,
oauthTokenSecret: oauthResult.oauth_token_secret,
oauthCallbackConfirmed: oauthResult.oauth_callback_confirmed
};
}
getTokens = async (oauthToken: string, oauthVerifier: string): Promise<any> => {
const endpoint = 'https://api.twitter.com/oauth/access_token';
const data = {
oauth_consumer_key: this.config.apiKey,
oauth_token: oauthToken,
oauth_verifier: oauthVerifier,
};
const response: any = await fetch(`${endpoint}?${new URLSearchParams(data)}`, { method: 'POST' });
// This endpoint returns query string like key-value pairs
// https://developer.twitter.com/en/docs/authentication/api-reference/access_token
return Object.fromEntries([...(new URLSearchParams(await response.text()))]);
}
getUserProfile = async ({ oauth_token, oauth_token_secret, ...account }: any) => {
let user: any = {};
try {
// Need to apply for elevated access - not tested yet
user = await (new TwitterApi({
appKey: this.config.apiKey,
appSecret: this.config.apiSecret,
accessToken: oauth_token,
accessSecret: oauth_token_secret,
})).readOnly.currentUser();
} catch (e) {
// 403
}
return { ...user, ...account };
}
getCallbackUri(): string {
return `${settings.AUTH_CALLBACK_URI_PREFIX}twitter`;
}
},
... |
Hey! When you mean using your own here. There's a reference to "new TwitterApi" in there. Where are you getting this from? |
O sorry the link above doesn't work... I employed this twitter-api-v2 library |
I did something like this to support OAuth 1.0a with Twitter: import { TwitterAuthProvider } from "sk-auth/providers";
import { TwitterApi } from 'twitter-api-v2';
const twitterProfileHandler = ({ id, id_str, name, screen_name, description, profile_image_url, profile_image_url_https, verified }) => ({
id, id_str, name, screen_name, description, profile_image_url, profile_image_url_https, verified
});
const defaultConfig = {
id: "twitter",
profile: twitterProfileHandler,
}
export class TwitterV2AuthProvider extends TwitterAuthProvider {
constructor(config) {
super({
...defaultConfig,
...config
})
}
async getRequestToken(auth, host, state) {
const { url, ...oauthResult } = await (new TwitterApi({
appKey: this.config.apiKey,
appSecret: this.config.apiSecret
})).readOnly.generateAuthLink(
encodeURIComponent(this.getCallbackUri(auth, host, state)), { authAccessType: 'read' }
);
return {
oauthToken: oauthResult.oauth_token,
oauthTokenSecret: oauthResult.oauth_token_secret,
oauthCallbackConfirmed: oauthResult.oauth_callback_confirmed
};
}
getCallbackUri(svelteKitAuth, host, state) {
return this.getUri(svelteKitAuth, `${"/callback/"}${this.id}?state=${state}`, host);
}
async getAuthorizationUrl({ url }, auth, state, nonce) {
const endpoint = "https://api.twitter.com/oauth/authorize";
const { oauthToken } = await this.getRequestToken(auth, url.host, state);
const data = {
oauth_token: oauthToken,
redirect_uri: this.getCallbackUri(auth, url.host, state),
};
const authUrl = `${endpoint}?${new URLSearchParams(data)}`;
return authUrl;
}
async getTokens(oauthToken, oauthVerifier) {
const endpoint = 'https://api.twitter.com/oauth/access_token';
const data = {
oauth_consumer_key: this.config.apiKey,
oauth_token: oauthToken,
oauth_verifier: oauthVerifier,
};
const response = await fetch(`${endpoint}?${new URLSearchParams(data)}`, { method: 'POST' });
// This endpoint returns query string like key-value pairs
// https://developer.twitter.com/en/docs/authentication/api-reference/access_token
return Object.fromEntries([...(new URLSearchParams(await response.text()))]);
}
async getUserProfile({ oauth_token, oauth_token_secret, ...account }) {
let user = {};
try {
user = await (new TwitterApi({
appKey: this.config.apiKey,
appSecret: this.config.apiSecret,
accessToken: oauth_token,
accessSecret: oauth_token_secret,
})).readOnly.currentUser();
} catch (e) {
console.error('could not get current user: ', e)
return {};
}
return { ...user, ...account, oauth_token, oauth_token_secret };
}
async callback(event, auth) {
const { url } = event;
const oauthToken = url.searchParams.get("oauth_token");
const oauthVerifier = url.searchParams.get("oauth_verifier");
const redirect = this.getStateValue(url.searchParams, "redirect");
const tokens = await this.getTokens(oauthToken, oauthVerifier);
let user = await this.getUserProfile(tokens);
if (this.config.profile) {
user = await this.config.profile(user, tokens);
}
return [user, redirect ?? this.getUri(auth, "/", url.host)];
}
}
TwitterV2AuthProvider.profileHandler = twitterProfileHandler; and then incorporate it into my auth configuration: export const appAuth = new SvelteKitAuth({
protocol: import.meta.env.VITE_OAUTH_PROTOTCOL,
providers: [
new TwitterV2AuthProvider({
apiKey: import.meta.env.VITE_TWITTER_API_KEY,
apiSecret: import.meta.env.VITE_TWITTER_API_SECRET,
profile: (profile, tokens) => {
const slim = TwitterV2AuthProvider.profileHandler(profile);
return { ...slim, tokens: { oauth_token: tokens.oauth_token, oauth_token_secret: tokens.oauth_token_secret }, provider: "twitter" };
},
}),
],
callbacks: {
... |
Tried with Twitter, and it doesn't seems like working?
It gets stuck at a Twitter Error page at
https://api.twitter.com/oauth/authorize?oauth_token=undefined
.The text was updated successfully, but these errors were encountered: