CircleCI, AWS Cognito, Amplify and Github Login
Tags: aws
Published: 2020-05-15 15:53:05

[Uclusion](https://www.uclusion.com/?utm_source=devto&utm_medium=blog&utm_campaign=devgithublogin) is built on a relatively pure AWS stack and uses [Cognito](https://aws.amazon.com/cognito) and [Amplify](https://docs.amplify.aws/lib/auth/getting-started/q/platform/js) Auth for user authentication.

If you are too, and want to enable login with GitHub here’s how you do it.

Step 1: Bridge OpenID Connect and Github Oauth2.

Unfortunately, Cognito and GitHub can’t directly talk with each other because Cognito supports SAML and OIDC while GitHub only supports Oauth. Fortunately, there exists an open source shim, the [GitHub OpenID Connect Wrapper for Cognito](https://github.com/TimothyJones/github-cognito-openid-wrapper) that bridges the Gap.

The wrapper has two basic modes of operation, as a lambda with API gateway, and as a standalone node instance. We’re Lambda based ourselves, so we went with that option. The readme.md of the Wrapper does a good job of describing the setup steps for [Cognito](https://github.com/TimothyJones/github-cognito-openid-wrapper#3-finalise-cognito-configuration) and [here are the instructions for creating an Oauth app in Github](https://developer.github.com/apps/building-oauth-apps/), so I’ll just be focusing on how to get the shim working with CircleCI and Amplify.

Step 2: Create a CircleCI config.

Since we use CircleCI we needed a way to deploy the lambda along side our existing [Serverless Framework](https://www.serverless.com/) based stacks, even though the Wrapper uses aws cli and aws sam. It turns out that’s not to hard with a good [CircleCI config.yml](https://circleci.com/docs/2.0/sample-config/).Here’s ours:

    version: 2
    jobs:
      build:
        docker:
          - image: circleci/python:3.7.2
    
        working_directory: ~/repo
    
        steps:
          - checkout
          - run:
              name: get node repo
              command: wget -qO- https://deb.nodesource.com/setup_10.x | sudo -E bash -
          - run:
              name: install node
              command: sudo apt-get install -y nodejs
          - run:
              name: Get aws cli
              command: sudo pip install awscli
          - run:
              name: Get aws sam
              command: sudo pip install aws-sam-cli
          - run:
              name: Setup config
              command: cp $env_name-config.sh config.sh
          - run:
              name: Install NPM deps
              command: npm install
          - run:
              name: Deploy
              command: npm run deploy
    
    workflows:
      version: 2
      deploy-dev:
        jobs:
          - build:
              filters:
                tags:
                  only: /^dev_backend.*/
                branches:
                  ignore: /.*/
              context: dev

The file basically sets up node, cli and sam, and makes use of [CircleCI Environment Variables](https://circleci.com/docs/2.0/env-vars/) to establish our AWS credentials, to specify which version of the env name we’re deploying (dev, stage, production), and to set up auto workflow (in this case just dev) so we can auto deploy when we do releases with the tags dev_backend.

To use this file, fork the Wrapper’s repo, and create the file .circleci/config.yml inside the root of the new repo. Then go into CircleCI and tell it to monitor the project. If you haven’t configured your CircleCI to automatically respond to GitHub events the directions are here: [https://circleci.com/docs/2.0/project-build/](https://circleci.com/docs/2.0/project-build/)

Step 3: Tell Amplify to log in with your new provider:

When you setup the OIDC source in Cognito according to the [directions in the wrapper](https://github.com/TimothyJones/github-cognito-openid-wrapper#3-finalise-cognito-configuration), you gave the integration a name. Lets assume that name was ‘GithubLogin’.

If you’ve already [configured Amplify for federated login with Google or Facebook](https://docs.amplify.aws/lib/auth/social/q/platform/js) (which you really should do unless you have a good reason not to), then Amplify makes using your new provider really easy. All you have to do is change the ‘provider’ flag when doing federated logins to ‘GithubLogin’.

    <Button onClick={() => Auth.federatedSignIn({provider: 'GithubLogin'})}>Github Login</Button>

You’ll want to style that and make it fancier of course, but that’s all it takes. Assuming everything has been set up correctly you can now log in with Github Identities.

Things I haven’t told you:

1. Custom Domains: You should really have a custom domain for your Cognito Pool and your API gateway, as things will look much more professional. Instructions for Cognito are [here](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-add-custom-domain.html), and for API gateway are [here](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html).

1. Post login workflows: You’ll probably want to do something fancy with the GitHub users so make sure to inspect the Amplify user attributes on your pages, as Cognito will helpfully tell you that the user came from ‘GithubLogin’. The attributes can be gotten via code like this:

    Auth.currentAuthenticatedUser()
      .then((user) => {
        const { attributes } = user;

See the Javascript in production code [here](https://github.com/Uclusion/uclusion_web_ui/blob/master/src/pages/Authentication/Signup.js).