how to authenticate the linkedin API

The OAuth 2.0 Protocol is a third party protocol used for authentication and authorization. In this article, we will see how to authenticate the LinkedIn API using OAuth 2.0 and Python.

If you haven’t already, make sure that you read how to get LinkedIn API OAuth credentials before starting this tutorial.


This post is part of the complete guide on how to use the LinkedIn API with Python

Join the Newsletter

    1. Get Your OAuth Credentials
    2. Authenticate Using OAuth 2.0
    3. Get Your Own User Information
    4. Simple Steps to Find Any Company ID on LinkedIn
    5. How to Post On LinkedIn API With Python
    6. How to Scrape LinkedIn Jobs with Python

    Import Libraries

    To run the OAuth 2.0 authentication you will need to install and import all those libraries: requests, random, string and json.

    import json
    import random
    import requests
    import string
    

    Read Credentials

    Now, let’s create a function that will read the credentials.json file that we have created in

    def read_creds(filename):
        '''
        Store API credentials in a safe place.
        If you use Git, make sure to add the file to .gitignore
        '''
        with open(filename) as f:
            credentials = json.load(f)
        return credentials
    
    creds = read_creds('credentials.json')
    client_id, client_secret = creds['client_id'], creds['client_secret']
    redirect_uri = creds['redirect_uri']
    

    Authorize The API

    To authorize the API, you will need to generate a CSRF token to prevent cross-site request forgery. The create_CSRF_token() function does this.

    It creates a random string of letters to use as the CSRF Token.

    def create_CSRF_token():
        '''
        This function generates a random string of letters.
        It is not required by the Linkedin API to use a CSRF token.
        However, it is recommended to protect against cross-site request forgery
        '''
        letters = string.ascii_lowercase
        token = ''.join(random.choice(letters) for i in range(20))
        return token
    

    Then, the authorize() function says what it does. It will open the authentication URL. Once authorized, it’ll redirect to the redirect URI given.

    api_url = 'https://www.linkedin.com/oauth/v2' 
    
    def authorize(api_url,client_id,client_secret,redirect_uri):
        '''
        Make a HTTP request to the authorization URL.
        It will open the authentication URL.
        Once authorized, it'll redirect to the redirect URI given.
        The page will look like an error. but it is not.
        You'll need to copy the redirected URL.
        '''
        # Request authentication URL
        csrf_token = create_CSRF_token()
        params = {
            'response_type': 'code',
            'client_id': client_id,
            'redirect_uri': redirect_uri,
            'state': csrf_token,
            'scope': 'r_liteprofile,r_emailaddress,w_member_social'
            }
    
        response = requests.get(f'{api_url}/authorization',params=params)
    
        print(f'''
        The Browser will open to ask you to authorize the credentials.\n
        Since we have not set up a server, you will get the error:\n
        This site can’t be reached. localhost refused to connect.\n
        This is normal.\n
        You need to copy the URL where you are being redirected to.\n
        ''')
    
        open_url(response.url)
    
        # Get the authorization verifier code from the callback url
        redirect_response = input('Paste the full redirect URL here:')
        auth_code = parse_redirect_uri(redirect_response)
        return auth_code
    

    Get the Access Token

    The authorize() function contains two functions that we need to define: open_url() and parse_redirect_uri().

    The former opens the login URL in the browser.

    def open_url(url):
        '''
        Function to Open URL.
        Used to open the authorization link
        '''
        import webbrowser
        print(url)
        webbrowser.open(url)
    

    The latter checks the redirect uri and extract the access token from it.

    def parse_redirect_uri(redirect_response):
        '''
        Parse redirect response into components.
        Extract the authorized token from the redirect uri.
        '''
        from urllib.parse import urlparse, parse_qs
    
        url = urlparse(redirect_response)
        url = parse_qs(url.query)
        return url['code'][0]
    

    A third function will be needed to save the access token to your credentials.json file.

    The save_token() function will make sure that you don’t need to log-in each time.

    def save_token(filename,data):
        '''
        Write token to credentials file.
        '''
        data = json.dumps(data, indent = 4) 
        with open(filename, 'w') as f: 
            f.write(data)
    

    A last function will not be used here, but later when we query the LinkedIn API.

    The headers() function creates the header that will be use in the request made to the API.

    def headers(access_token):
        '''
        Make the headers to attach to the API call.
        '''
        headers = {
        'Authorization': f'Bearer {access_token}',
        'cache-control': 'no-cache',
        'X-Restli-Protocol-Version': '2.0.0'
        }
        return headers
    

    Combine All Functions

    Now that we have all necessary functions, let’s make a function to run the entire script.

    The logic behind the auth() function goes like this:

    • Run the Authentication.
    • The first time the function runs, the browser opens asking you to authenticate.
    • You will have to manually paste the redirect URI in the prompt.
    • The URL will be parsed to extract the access token.
    • It will save the access token
    • Next time, it will use the access token instead of asking you to authenticate.
    def auth(credentials):
        '''
        Run the Authentication.
        If the access token exists, it will use it to skip browser auth.
        If not, it will open the browser for you to authenticate.
        You will have to manually paste the redirect URI in the prompt.
        '''
        creds = read_creds(credentials)
        print(creds)
        client_id, client_secret = creds['client_id'], creds['client_secret']
        redirect_uri = creds['redirect_uri']
        api_url = 'https://www.linkedin.com/oauth/v2' 
            
        if 'access_token' not in creds.keys(): 
            args = client_id,client_secret,redirect_uri
            auth_code = authorize(api_url,*args)
            access_token = refresh_token(auth_code,*args)
            creds.update({'access_token':access_token})
            save_token(credentials,creds)
        else: 
            access_token = creds['access_token']
        return access_token
    

    Run the Function

    To run the function, call the auth() function using the path to your credentials.json file.

    if __name__ == '__main__':
        credentials = 'credentials.json'
        access_token = auth(credentials)
    

    The if name equals main line checks whether you are running the module or importing it. If you are importing it, auth() will not run.

    I run the ln_oauth.py script that I just created using command-line.

    $ python ln_oauth.py
    

    Here is what happens.

    1. Browser opens asking me to login Linkedin

    2. Asks me to Allow the App

    3. I am Redirected to a Page that Can’t be Reached

    This is normal because I don’t run this on a server. Just copy the localhost:8080/?code... url.

    4. Copy the URL in your Script

    The access token is found right after the ?code= parameter and before the &state parameter.

    You could add the access token straight into your credentials.json file, or copy it in the prompt of your terminal.

    5. The Access Token is then Saved

    This is it, in the next post, we are going to see how to use the LinkedIn API using that access token.

    Full Code

    #!/usr/bin/env python
    '''
    Simple Authentication script to log-on the Linkedin API
    
    @author:    Jean-Christophe Chouinard. 
    @role:      Sr. SEO Specialist at SEEK.com.au
    @website:   jcchouinard.com
    @LinkedIn:  linkedin.com/in/jeanchristophechouinard/ 
    @Twitter:   twitter.com/@ChouinardJC
    '''
    import json
    import random
    import requests
    import string
    
    def auth(credentials):
        '''
        Run the Authentication.
        If the access token exists, it will use it to skip browser auth.
        If not, it will open the browser for you to authenticate.
        You will have to manually paste the redirect URI in the prompt.
        '''
        creds = read_creds(credentials)
        print(creds)
        client_id, client_secret = creds['client_id'], creds['client_secret']
        redirect_uri = creds['redirect_uri']
        api_url = 'https://www.linkedin.com/oauth/v2' 
            
        if 'access_token' not in creds.keys(): 
            args = client_id,client_secret,redirect_uri
            auth_code = authorize(api_url,*args)
            access_token = refresh_token(auth_code,*args)
            creds.update({'access_token':access_token})
            save_token(credentials,creds)
        else: 
            access_token = creds['access_token']
        return access_token
    
    def headers(access_token):
        '''
        Make the headers to attach to the API call.
        '''
        headers = {
        'Authorization': f'Bearer {access_token}',
        'cache-control': 'no-cache',
        'X-Restli-Protocol-Version': '2.0.0'
        }
        return headers
    
    def read_creds(filename):
        '''
        Store API credentials in a safe place.
        If you use Git, make sure to add the file to .gitignore
        '''
        with open(filename) as f:
            credentials = json.load(f)
        return credentials
    
    def save_token(filename,data):
        '''
        Write token to credentials file.
        '''
        data = json.dumps(data, indent = 4) 
        with open(filename, 'w') as f: 
            f.write(data)
    
    def create_CSRF_token():
        '''
        This function generate a random string of letters.
        It is not required by the Linkedin API to use a CSRF token.
        However, it is recommended to protect against cross-site request forgery
        For more info on CSRF https://en.wikipedia.org/wiki/Cross-site_request_forgery
        '''
        letters = string.ascii_lowercase
        token = ''.join(random.choice(letters) for i in range(20))
        return token
    
    def open_url(url):
        '''
        Function to Open URL.
        Used to open the authorization link
        '''
        import webbrowser
        print(url)
        webbrowser.open(url)
    
    def parse_redirect_uri(redirect_response):
        '''
        Parse redirect response into components.
        Extract the authorized token from the redirect uri.
        '''
        from urllib.parse import urlparse, parse_qs
    
        url = urlparse(redirect_response)
        url = parse_qs(url.query)
        return url['code'][0]
    
    def authorize(api_url,client_id,client_secret,redirect_uri):
        # Request authentication URL
        csrf_token = create_CSRF_token()
        params = {
            'response_type': 'code',
            'client_id': client_id,
            'redirect_uri': redirect_uri,
            'state': csrf_token,
            'scope': 'r_liteprofile,r_emailaddress,w_member_social'
            }
    
        response = requests.get(f'{api_url}/authorization',params=params)
    
        print(f'''
        The Browser will open to ask you to authorize the credentials.\n
        Since we have not setted up a server, you will get the error:\n
        This site can’t be reached. localhost refused to connect.\n
        This is normal.\n
        You need to copy the URL where you are being redirected to.\n
        ''')
    
        open_url(response.url)
    
        # Get the authorization verifier code from the callback url
        redirect_response = input('Paste the full redirect URL here:')
        auth_code = parse_redirect_uri(redirect_response)
        return auth_code
    
    def refresh_token(auth_code,client_id,client_secret,redirect_uri):
        '''
        Exchange a Refresh Token for a New Access Token.
        '''
        access_token_url = 'https://www.linkedin.com/oauth/v2/accessToken'
    
        data = {
            'grant_type': 'authorization_code',
            'code': auth_code,
            'redirect_uri': redirect_uri,
            'client_id': client_id,
            'client_secret': client_secret
            }
    
        response = requests.post(access_token_url, data=data, timeout=30)
        response = response.json()
        print(response)
        access_token = response['access_token']
        return access_token
    
    if __name__ == '__main__':
        credentials = 'credentials.json'
        access_token = auth(credentials)
    

    This is it, in the next post, we are going to see how to make your first API call using the LinkedIn API.

    5/5 - (6 votes)