oauth-2.0openid-connectonelogin

Can I run a OIDC flow from a command line CLI tool?


I'm running an OIDC flow to get access and ID tokens on a single-page application (I use OneLogin but that's probably not very relevant, it's a vanilla OIDC flow). I use the access token to call my backend APIs.

I want to provide the same functionality (including calling the same backend) from a command line tool. Is there a standard way to get the access token the same way I do it in the browser?

I'd consider any solutions including completing part of the flow in the browser, alternatives to OIDC, etc.


Solution

  • A console app is a native app and can run a code flow and listen for the OAuth response using one of the techniques from RFC8252:

    Here is some partial Javascript code for the first case. For an example of the second case see my desktop code sample.

    import Http from 'http';
    import Opener from 'opener';
    
    export async function login(): Promise<string> {
    
        const codeVerifier = generateRandomString();
        const codeChallenge = generateHash(codeVerifier);
        const state = generateRandomString();
        const authorizationUrl = buildAuthorizationUrl(state, codeChallenge);
    
        return new Promise<string>((resolve, reject) => {
    
            let server: Http.Server | null = null;
            const callback = async (request: Http.IncomingMessage, response: Http.ServerResponse) => {
    
                if (server != null) {
    
                    response.write('Login completed for the console client ...');
                    response.end();
                    server.close();
                    server = null;
    
                    try {
    
                        // Swap the code for tokens
                        const accessToken = await redeemCodeForAccessToken(request.url!, state, codeVerifier);
                        resolve(accessToken);
    
                    } catch (e: any) {
                        reject(e);
                    }
                }
            }
    
            server = Http.createServer(callback);
            server.listen(loopbackPort);
            
            Opener(authorizationUrl);
        });
    }