TeeWhy
TeeWhy

Reputation: 11

authlib for linkedin and fastapi

I am trying to create a login using linkedIn and authlib, but I'm running into errors when I try and receive my token. I am able to redirect to the linked in authentication and then redirect to my callback. But im having issues with the authorized_access_token(request).

Can someone help check if my implementation is correct?

This is the error im recieving:

{"error":"invalid_request: A required parameter "client_secret" is missing"}

oauth.register(
    "linkedin",
    client_id=LINKEDIN_CLIENT_ID,
    client_secret=LINKEDIN_CLIENT_SECRET,
    api_base_url='https://api.linkedin.com/v2/',
    authorize_url='https://www.linkedin.com/oauth/v2/authorization',
    access_token_url='https://www.linkedin.com/oauth/v2/accessToken',
    client_kwargs={'scope': 'openid profile email'}, 
)


@router.get('/login')
async def linkedin_login(request: Request):
    linkedin = oauth.create_client('linkedin')
    if linkedin:
        print(linkedin.name)
        redirect_uri = request.url_for('linkedin_auth')
        print(redirect_uri)
        return await linkedin.authorize_redirect(request, redirect_uri)
    else:
        return {'error': 'linkedin client not found'}
    
@router.get('/auth')
async def linkedin_auth(request: Request):
    linkedin = oauth.create_client('linkedin')
    if linkedin:
        try:
            token = await linkedin.authorize_access_token(request)
            return token
        except Exception as e:
            return {'error': str(e)}

I have tried changing the registration configurations and that doesnt seem to help. I believe my implementation is correct, but I am still getting errors

Upvotes: 1

Views: 513

Answers (1)

Oluwafemi Sule
Oluwafemi Sule

Reputation: 38922

The request passed in the authorize_access_token call is missing the client_secret to fetch the access token.

I have assumed that you are developing with FastAPI framework.

Some improvements over your code:

  1. Provide sensitive environment configuration in a .env file.
  2. Register the session middleware to keep the auth state. Otherwise you'll get a CSRF error.
from fastapi import FastAPI
from starlette.config import Config
from starlette.middleware.sessions import SessionMiddleware
from starlette.requests import Request
from authlib.integrations.starlette_client import OAuth

oauth = OAuth()
app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key=config.get('SECRET_KEY'))


config = Config('.env')
oauth = OAuth(config)

oauth.register(
    name="linkedin",
    api_base_url='https://api.linkedin.com/v2/',
    authorize_url='https://www.linkedin.com/oauth/v2/authorization',
    access_token_url='https://www.linkedin.com/oauth/v2/accessToken',
    client_kwargs={'scope': 'r_ads r_basicprofile'}, 
)


@app.get('/login')
async def linkedin_login(request: Request):
    redirect_uri = request.url_for('linkedin_auth')
    return await oauth.linkedin.authorize_redirect(request, redirect_uri)

    
@app.get('/auth')
async def linkedin_auth(request: Request):
    token = await oauth.linkedin.authorize_access_token(
        request, 
        client_secret=config.get('LINKEDIN_CLIENT_SECRET')
    )
    return token

Upvotes: 1

Related Questions