Skip to content
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

Error: access_token is required #71

Open
alexdpoon opened this issue Apr 11, 2023 · 8 comments
Open

Error: access_token is required #71

alexdpoon opened this issue Apr 11, 2023 · 8 comments

Comments

@alexdpoon
Copy link

When trying to post a new tweet with client.tweets.createTweet(), I get Error: access_token is required

Expected behavior

I expect the post to be created without error.

Actual behavior

Exception is thrown with Error: access_token is required

Steps to reproduce the behavior

After getting what looks to be a valid token using the code gotten from the callback:

const token = await authClient.requestAccessToken(code);

I create an authClient and client

let authClient = new auth.OAuth2User({
    client_id: TWITTER_OAUTH2_CLIENT_ID as string,
    client_secret: TWITTER_OAUTH2_CLIENT_SECRET as string,
    callback: "http://localhost:3001/oauth2/callback",
    scopes: ["tweet.read", "users.read", "tweet.write", "offline.access"],
    token
  });
let client = new Client(authClient);

Then I try to create the tweet using:

const request_body: any = { text }
const response = await client.tweets.createTweet(request_body)

but I get an exception thrown with Error: access_token is required

BTW, the token i'm passing into new auth.OAuth2User looks like:

    {
      token: {
        token_type: 'bearer',
        access_token: 'ZTE0eHlBNVE2WEV3MkdaQ3Vidk5--redacted--Tg4MjMzMDA6MTowOmF0OjE',
        scope: 'tweet.write users.read tweet.read offline.access',
        refresh_token: 'aU5aRjZxV0EtZDRYTnAwZHBGWU1uY3hmZW9tUC01Z--redacted--g4MjMzMDA6MTowOnJ0OjE',
        expires_at: 1681206020512
      }
    }
@alexdpoon
Copy link
Author

Figured it out myself. Needed to send token.token instead of token when creating the authClient. As in:


let authClient = new auth.OAuth2User({
    client_id: TWITTER_OAUTH2_CLIENT_ID as string,
    client_secret: TWITTER_OAUTH2_CLIENT_SECRET as string,
    callback: "http://localhost:3001/oauth2/callback",
    scopes: ["tweet.read", "users.read", "tweet.write", "offline.access"],
    token: token.token
  });
let client = new Client(authClient);

@RafayelKh
Copy link

Hey @alexdpoon, hope you are doing well!
Just one quick question about token object. Where did you find refresh_token? Thanks.

@ojmarte
Copy link

ojmarte commented Oct 27, 2023

@RafayelKh, you can reference the token property of the OAuth2User class in the Twitter API TypeScript SDK here. This property implements the GetTokenResponse interface, which includes the refresh_token type. You can view its detailed structure in the same file.

interface GetTokenResponse {
  /** Allows applications to obtain a new access token without user prompt using the refresh token flow. */
  refresh_token?: string;
  /** Tokens that applications utilize to make API requests on a user's behalf. */
  access_token?: string;
  token_type?: string;
  expires_in?: number;
  /** A comma-separated list detailing the scope of the token. */
  scope?: string;
}

I hope this helps clarify things!

@feresr
Copy link

feresr commented Nov 25, 2023

@ojmarte Why isn't the Token type exported? (for typescript)
This is the object we're supposed to store in db (to avoid asking users to re-auth) right?

@ojmarte
Copy link

ojmarte commented Nov 25, 2023

Hey! @feresr, regarding your question about why the Token type isn't exported in the Twitter API TypeScript SDK: From what I understand, it seems that the Token type, being part of the OAuth2UserOptions interface, might be primarily intended for in-app OAuth interactions and not specifically designed with database storage in mind. However, this is just my take on it, and the actual reason might be different based on the SDK's design decisions.

export interface OAuth2UserOptions {
  /** Can be found in the developer portal under the header "Client ID". */
  client_id: string;
  /** If you have selected an App type that is a confidential client you will be provided with a “Client Secret” under “Client ID” in your App’s keys and tokens section. */
  client_secret?: string;
  /**Your callback URL. This value must correspond to one of the Callback URLs defined in your App’s settings. For OAuth 2.0, you will need to have exact match validation for your callback URL. */
  callback: string;
  /** Scopes allow you to set granular access for your App so that your App only has the permissions that it needs. To learn more about what scopes map to what endpoints, view our {@link https://developer.twitter.com/en/docs/authentication/guides/v2-authentication-mapping authentication mapping guide}. */
  scopes: OAuth2Scopes[];
  /** Overwrite request options for all endpoints */
  request_options?: Partial<RequestOptions>;
  /** Set the auth token */
  token?: Token;
}

@feresr
Copy link

feresr commented Nov 25, 2023

Thanks for the quick reply @ojmarte !

Im storing this Token in the user session. I wouldn't want to store the entirety of OAuth2UserOptions because it contains sensitive info (like client_secret).

I wonder if this is the intended usage.🤔
Hopefully we get some answer from the repo owners

@akoskm
Copy link

akoskm commented Jan 13, 2024

Hey @alexdpoon, hope you are doing well! Just one quick question about token object. Where did you find refresh_token? Thanks.

Note that offline.access must be enabled to get a refresh_token.

If the scope offline.access is applied an OAuth 2.0 refresh token will be issued.
https://developer.twitter.com/en/docs/authentication/oauth-2-0/authorization-code

@programador51
Copy link

Figured it out myself. Needed to send token.token instead of token when creating the authClient. As in:


let authClient = new auth.OAuth2User({
    client_id: TWITTER_OAUTH2_CLIENT_ID as string,
    client_secret: TWITTER_OAUTH2_CLIENT_SECRET as string,
    callback: "http://localhost:3001/oauth2/callback",
    scopes: ["tweet.read", "users.read", "tweet.write", "offline.access"],
    token: token.token
  });
let client = new Client(authClient);

God damn...

Thank you for this info, the docs and example don't specify this to make it work. I had struggle, I thought the methods will just set some cookies and the library read the tokens from there, tried of everything but just worked a was able to make a twitter post 😀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants