An AWS Lambda function to handle the oauth client secret part of oauth so that your webpage can allow users to login to oauth services.
If you look through the OAuth flow, at least for Github and I guess I'm assuming the rest are the same then you'll see it works like this
-
User clicks some login button on your webpage
-
Your webpage opens a popup or iframe to the oauth login page for the service you want them to login
In the URL you include 3 search parameters
- the
client_id
assigned to your app when you registered it with the service. - the
scope
which is the features of their account you want to access with your app - a
state
string which is some extra data you make up and use later to make sure the request is legit
- the
-
The user logs in via the popup/iframe and then is presented with some page that says something like
app "XYZ" wants to permission to do A, B, and C (read your email address, look at your friend list, etc..)
If the user clicks ok then
-
The service (in this case github) redirects the browser to a URL you pre-registred when you added the app and includes a
code
, which at least with github, is valid for 10 minutes. It also includes thestate
you sent previously so you can check it's the same as when you sent it. This allows you to prevent someone from going directly the the page you registered as the URL for github to send you the code. -
Your page that github redirected the user's browser to then needs contact github at a different URL and pass it the
code
, your app'sclient_id
and aclient_secret
(also from when you registered the app. This is where this repo comes it.The fact that it's a "client_secret" means this secret can't be stored in your webpage. It has to be on a server somewhere. That's where this repo's function comes in. You setup this funciton on AWS Lambda, you connect it to AWS API Gateway. Your webpage then contacts this function via some URL at Amazon, sending it the
code
, andclient_id
. The function then contacts github adding in theclient_secret
. In return you get back anaccess_token
which is effectively a password for the user's github account that lets your app do the things you requested permission to do above. Where you store that is up to you but it is a password with no username required and anyone that has it can do anything you asked permission for.
-
Create an AWS account
-
Find AWS Lambda
-
Create a Function
-
In the code area for index.js paste the contents of aws-oauth-helper.js. Then click "Deploy"
-
Scroll down and where it says environment variables add a key in the form
c_<client_id>
whereclient_id
is given to you by github when you registered your app. Note thec_
before the rest of the id. This is because ids can start with a number so we add the prefixc_
. For the value, paste in the secret key, also given to you when you registered your app. Also add another variable, keye_<client_id>
and set the value to the endpoint for getting the access token from the service. In the case of github it'shttps://github.com/login/oauth/access_token
. In other wordskey value ---------------+------------------ c_<client_id> | <client_secret> e_<client_id> | <endpoint>
Mine look something like this
c_34093c3c2eeb4dc7fd0f 3eb4d4093c3c2ec7fd0f3c2eeb4dc7fd0f34093c e_34093c3c2eeb4dc7fd0f https://github.com/login/oauth/access_token
-
Back at the top you'll see a "Designer" diagram. Click the "Add Triggers" button
-
Select the API Gateway as a trigger
-
Create an API, REST API, Security: Open and click Add
-
Now below the diagram you should see API gateway and a link to the API you just created. Click that link
-
In the left panel select "Resources"
-
At the top of the middle column click the "Actions" button and pick "Deploy API". When asked for a stage pick "default"
-
Now click stages on the left
-
In the middle column, click the little triangle/arrow next to default to open it up, then again open the
/
under that, and the next thing under that, then click on "GET". -
On the right panel you'll see a URL. This is the URL needed at step 5 above. Your webpage would do something like
// some async function const url = `${urlFromAWSPanel}?code=${codeFromGithubStep4Above}&clientId=${clientIdFromGithub}`; const req = await fetch(url); const data = await req.json(); if (data.access_token) { // success. Use this as the auth parameter to something iike Octokit:rest https://octokit.github.io/rest.js/v18 } else { // failure. }
Note that most likely it would be good for you to register a domain name and then in the AWS API Gateway register some subdomain as a custom domain name for your API. That way instead of have to fetch to something like https://30923eifjifj.execute-api.us-east2.amazonaws.com/default
you could use https://myapi.mycustomdomain.com/api-name
Thanks to https://github.com/HenrikJoreteg/github-secret-keeper which made it clear how simple this could be.