Skip to content

Instantly share code, notes, and snippets.

@viki53
Last active November 17, 2017 15:09
Show Gist options
  • Save viki53/a1474a26892d80e56b6dce767a350beb to your computer and use it in GitHub Desktop.
Save viki53/a1474a26892d80e56b6dce767a350beb to your computer and use it in GitHub Desktop.
Using Cognito authentication with AWS Cognito in API Gateway
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { AuthGuardService } from './auth-guard.service';
import { AWS_APIGW_ID, AWS_REGION } from '../conf/aws.const';
export const API_ROOT = `https://${AWS_APIGW_ID}.execute-api.${AWS_REGION}.amazonaws.com/prd`;
@Injectable()
export class ApiService {
constructor(
private auth: AuthGuardService,
private http: HttpClient,
) {}
public getData(): Observable<any> {
return this.http.get(`${API_ROOT}/any-endpoint-you-want`, {
headers: this.getHeaders()
});
}
private getHeaders(): HttpHeaders {
let headers = new HttpHeaders();
headers = headers.append('Authorization', this.auth.idToken);
return headers;
}
}
import { Injectable } from '@angular/core';
import { OAuthResult } from '../models/oauth-result';
export const LOGIN_PAGE = '/auth/login';
@Injectable()
export class AuthGuardService implements CanActivate {
public get accessToken(): string {
return localStorage.getItem('access_token');
}
public set accessToken(value: string) {
if (value === null) {
localStorage.removeItem('access_token');
}
else {
localStorage.setItem('access_token', value);
}
}
public get idToken(): string {
return localStorage.getItem('id_token');
}
public set idToken(value: string) {
if (value === null) {
localStorage.removeItem('id_token');
}
else {
localStorage.setItem('id_token', value);
}
}
public get expiresAt(): Date {
const value = localStorage.getItem('expires_at');
return value ? new Date(value) : null;
}
public set expiresAt(value: Date) {
if (value === null) {
localStorage.removeItem('expires_at');
}
else {
localStorage.setItem('expires_at', value.toISOString());
}
}
public handleAuthentication(authResult: OAuthResult): void {
if (!authResult.isComplete()) {
this.router.navigate([LOGIN_PAGE]);
throw new Error('OAuth token is incomplete');
}
this.accessToken = authResult.access_token;
this.idToken = authResult.id_token;
const expiration = new Date();
expiration.setSeconds(expiration.getSeconds() + authResult.expires_in);
this.expiresAt = expiration;
this.router.navigate([HOME_PAGE]);
}
}
<p>
<a [href]="loginUrl">Sign in</a>
</p>
<p>
I have not signed up yet, I want to <a [href]="signupUrl">create an account</a>.
</p>
import { Component, OnInit } from '@angular/core';
import { OAuthResult } from '../models/oauth-result';
import { AuthGuardService } from '../services/auth-guard.service';
import { AWS_COGNITO_CLIENT_ID, AWS_COGNITO_DOMAIN } from '../conf/aws.const';
@Component({
selector: 'app-auth-login-page',
templateUrl: './login.html'
})
export class AuthLoginComponent implements OnInit {
public loginUrl: string;
public signupUrl: string;
constructor(
private auth: AuthGuardService
) {
this.loginUrl = `https://${AWS_COGNITO_DOMAIN}.auth.eu-west-1.amazoncognito.com/login?response_type=token&client_id=${AWS_COGNITO_CLIENT_ID}&redirect_uri=${encodeURIComponent(window.location.href.replace(window.location.hash, ''))}`;
this.signupUrl = `https://${AWS_COGNITO_DOMAIN}.auth.eu-west-1.amazoncognito.com/signup?response_type=token&client_id=${AWS_COGNITO_CLIENT_ID}&redirect_uri=${encodeURIComponent(window.location.href.replace(window.location.hash, ''))}`;
}
public ngOnInit() {
if (window.location.hash) {
const hash = window.location.hash.substr(1);
const result = new OAuthResult();
hash.split('&')
.forEach((param) => {
const [key, value] = param.split('=');
result[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : '';
}, {});
this.auth.handleAuthentication(result);
}
}
}

Swagger spec

# Declare your path
paths:
  /any-endpoint-you-want:
    get:
      summary: Get some date
      description: Returns any data you want
      security:
        - authenticated: []

# Declare your security rule
securityDefinitions:
  authenticated:
    type: "apiKey"
    name: "Authorization" # Header name
    in: "header"
    x-amazon-apigateway-authtype: "cognito_user_pools"
    x-amazon-apigateway-authorizer:
      providerARNs:
      - ${apigw_authorizer_cognito} # You user pool ARN, like 'arn:aws:cognito-idp:eu-west-1:123456123456:userpool/eu-west-1_a1z2e3r4t'
      type: "cognito_user_pools"

Client side (using Angular)

User Sign in

See auth-login.ts basic example

Declaring the proper headers using Angular:

See example in api.service.ts

interface OAuthResultInterface {
access_token?: string;
expires_in?: number;
id_token?: string;
token_type?: string;
created_at?: Date;
isComplete(): boolean;
}
export class OAuthResult implements OAuthResultInterface {
public access_token?: string;
public expires_in?: number;
public id_token?: string;
public token_type?: string;
public created_at?: Date = new Date();
constructor() {}
public isComplete(): boolean {
if (!this.access_token || !this.expires_in || !this.id_token || !this.token_type) {
return false;
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment