oauth2-cli

Command line utility to get an OAuth access token for three-legged flows where you authorise an application to access your account. Inspired by oauth2-cli written in Go.

The reason for rewriting this in Ruby was the difficulty to debug the OAuth2 flow when things don't go as expected. Go's OAuth2 library is pretty opaque and trying to figure out why for some services the client_id is not passed when sending the the token request after obtaining the authorisation code has been fruitless - even though sending the request via curl using the produced authorisation code proved successful.

The purpose for this tool is to obtain access and refresh tokens for applications which run as services (i.e daemons) where doing the OAuth2 flow is a bit difficult.

Install

gem install oauth2-cli

Usage

For services which validate the callback URL, you must use http://127.0.0.1:8000/oauth/callback in your OAuth2 application. Bear in mind that 8000 is the default port which may be changed via CLI argument. Adapt as necessary.

The oauth2-cli script has a built in help:

oauth2-cli -h
Usage: oauth2-cli --auth AUTHORISATION_URL --token TOKEN_URL --id CLIENT_ID --secret CLIENT_SECRET

    -a, --auth AUTHORISATION_URL     Authorisation URL (required)
    -t, --token TOKEN_URL            Token URL (required)
    -i, --id CLIENT_ID               Client ID (required)
    -s, --secret CLIENT_SECRET       Client secret (required)
    -o, --scope SCOPE1,SCOPE2,etc    OAuth2 scope to authorise (not used if not specified)
    -e, --separator                  OAuth2 scope separator character (defaults to space) n.b the scope arg is always passed as array and joined with the separator char for the request
    -p, --port 8000                  Callback port (defaults to 8000)
    -d, --debug                      Turn on OAuth2 library debug and WEBrick log

The scope separator character has been implemented for services which interpret the OAuth2 spec a tad different - for example Facebook is using comma separated values for scope.

Examples

# request tokens for accessing Netatmo Weather station
oauth2-cli -a https://api.netatmo.com/oauth2/authorize -t https://api.netatmo.com/oauth2/token -i CLIENT_ID -s CLIENT_SECRET -o read_station

Go to URL: https://api.netatmo.com/oauth2/authorize?access_type=offline&client_id=CLIENT_ID&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Foauth%2Fcallback&response_type=code&scope=read_station&state=ewcxkqpsfrinhgvyamzbouljtd

Starting server - use Ctrl+C to stop

{"scope"=>["read_station"],
 "expire_in"=>10800,
 :access_token=>"ACCESS_TOKEN",
 :refresh_token=>"REFRESH_TOKEN",
 :expires_at=>TIMESTAMP}

^C

# request tokens for accessing Awair air-quality monitor
oauth2-cli -a https://oauth-login.awair.is -t https://oauth2.awair.is/v2/token -i CLIENT_ID -s CLIENT_SECRET

Go to URL: https://oauth-login.awair.is?access_type=offline&client_id=CLIENT_ID&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Foauth%2Fcallback&response_type=code&state=jtiznuypwqfhbvmradlgkeoxcs

Starting server - use Ctrl+C to stop

{"token_type"=>"Bearer",
 :access_token=>"ACCESS_TOKEN",
 :refresh_token=>"REFRESH_TOKEN",
 :expires_at=>nil}

^C

The output hash from the token request may be used by Ruby's OAuth2 library to recreate an AccessToken object using the from_hash class method. You have to implement your own token refresh capabilities when the access token expires for the OAuth2 library doesn't provide such functionality.