Open rcfrias opened 7 years ago
FWIW it does work with Angular (4.x), though I've only tested with Webpack. I only needed to install amazon-cognito-auth-js
package through NPM (without aws-sdk
), and imported CognitoAuth
using
import { CognitoAuth } from 'amazon-cognito-auth-js/dist/amazon-cognito-auth';
Hope that helps.
thkx @dinvlad , I decided to import this in index.html:
<script src="app/aws-cognito-sdk.js"></script>
<script src="app/amazon-cognito-auth.js"></script>
and use it globally. I would have preferred to have it contained inside angular as a Module, but it was taking me too long to figure out how to do it. I've seen that most modules include typings and can be installed through npm. Until amazon-cognito-auth-js gets there, I think this is the only way to go while using system.js
Typings are not needed here, the module already contains ES6 classes to support TypeScript out of the box afaik.
Is there a working example for angular 4? I am still finding my feet with Angular atm.
@yhedaoo not for this project, at least not using system.js. It seems @dinvlad has tested with Webpack and I got it working with a global approach. (I am using system.js).
At the risk of citing a competitor solution, there's a very thorough guide from Auth0 on how to configure Angular (2+) with their library [1]. I followed it almost to the letter to configure CognitoAuth. The only difference is in how you instantiate this class, parse tokens in the callback, and get the session (arguably, it is actually easier now with CognitoAuth). Here's a rough sketch of my AuthService class, where all of CognitoAuth hides:
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { CognitoAuth } from 'amazon-cognito-auth-js/dist/amazon-cognito-auth';
export class AuthConfig {
constructor(
public readonly clientId: string,
public readonly domain: string,
) {}
}
@Injectable()
export class AuthService {
private readonly auth: CognitoAuth;
constructor(config: AuthConfig, private readonly router: Router) {
this.auth = new CognitoAuth({
ClientId: config.clientId,
AppWebDomain: config.domain,
TokenScopesArray: [],
RedirectUriSignIn: this.callbackUrl,
RedirectUriSignOut: this.callbackUrl,
});
this.auth.userhandler = {
onSuccess: session => this.onSuccess(session),
onFailure: () => this.onFailure(),
};
}
// have to construct callbackUrl from "scratch",
// as Angular doesn't appear to offer a native way to do it;
// '/login' is my callback route
private get callbackUrl() {
return window.location.href.split('/').slice(0, 3).concat('login').join('/');
// or window.location.origin + '/login';
}
// gets called by the callback component
login() {
this.auth.parseCognitoWebResponse(this.router.url);
this.auth.getSession();
}
// used to determine access in AuthGuard
isAuthenticated() {
return this.session && this.session.isValid();
}
private session;
private onSuccess(session) {
this.session = session;
this.router.navigateByUrl(this.guardedUrl);
}
private onFailure() {
this.session = undefined;
}
get accessToken() {
return this.session && this.session.getAccessToken().getJwtToken();
}
// save and restore initial route upon redirect from Cognito-hosted page
set guardedUrl(url: string) {
localStorage.setItem('guardedUrl', url);
}
get guardedUrl() {
return localStorage.getItem('guardedUrl') || '/';
}
}
Everything else may be done exactly the same as in [1].
the redirect back to localhost:4200/login seems to fail when I try it.. do you have a boilerplate angular4 application set up that I can possibly look at? Thanks
@yhedaoo I had the same problem, please look at this recommendations:
@yhedaoo yes, everything @rcfrias said needs to fall into place (although "code" method is not needed for Angular, unless it's server-side rendered). You do need to configure a /login route for redirect, or alternatively redirect to the base of your app but then call the login() method from ngOnit of your AppComponent. Unfortunately I'm still in the process of open-sourcing my application, but once it's ready I can share a link.
Btw if it's just an https error then you can easily enable ssl from ng serve
with --ssl --ssl-key path/to/your/self-signed.key --ssl-cert path/to/your/self-signed.cert
. The last 2 you generate with openssl
command line.
Does any of the suggestions work? @yhedaoo
I get this error on Ubuntu using angular
Cannot find module 'amazon-cognito-auth-js/dist/amazon-cognito-auth'.
Hi @dinvlad, could you help me understand a few things from your example?
I am able to go to the AWS created page and log in using facebook or google. I am returned a access_token in my callback, but I am not sure how I am supposed to capture this token? My callback is localhost:4200/callback, but as soon as my application goes to this route, it re-routes back to localhost:4200 and removes the hash.
Neither the onSuccess nor the onFailure functions are fired in my authService. Sorry if this is obvious stuff. I am fairly new to Angular.
@iamcootis sorry, not sure how to help. Generally, your Angular Router should be set up to direct your callback route to the Auth component that will invoke authService.login()
when hit.
Btw to anyone concerned, unfortunately I'm no longer using this library (we moved to Firebase). I'd defer to Amazon staff here for further help.
Hi @iamcootis, You need to call "auth.parseCognitoWebResponse(curUrl); ", which would have extracted the tokens from the url and invoked onSuccess()/onError() callbacks.
You can see the example in our sample line 97 to 112. https://github.com/aws/amazon-cognito-auth-js/blob/master/sample/index.html Here you can see that you need to initialize auth object first(line 194 to 216), then call "auth.getSession()" for sign-in, then call "auth.parseCognitoWebResponse(curUrl);" to parse the callback url containing tokens or code.
@yuntuowang The problem, and I think @dinvlad is having the same issue, is that your userhandler is not working in angular.
this.auth.userhandler = {
onSuccess: session => this.onSuccess(session),
onFailure: () => this.onFailure(),
};
This part of the code never gets triggered. Do you have a solution for that? Or an working angular example?
@marc101101 : Yes indeed. Same problem, userhandler is not working in angular, onSuccess and onFailure never being called
Fixed this problem. You have to init the handler bevore calling:
this.auth.parseCognitoWebResponse(this.router.url);
I still struggled to get the handlers firing. What made it click for me was the following:
The Component that will be loaded by the Router when the RedirectUriSignIn
url is activated should call the this.auth.parseCognitoWebResponse(this.router.url)
method, eg in the ngOnInit
method. That url will have the token/code added in the query string, and parsing that will trigger the onSuccess
handler, which in turn will give you your session object.
So while anything can call the this.auth.getSession()
to go to the AWS Cognito hosted web ui page, the callback Component (the Component linked by the Router to the RedirectUriSignIn
url you have configured) should parse the url to get the session.
Hope this helps someone.
It'd be nice to have some docs about how to use this in angular with System.Js. It is not clear to me if only with this project are we able to get a yes/no authentication, or we need to install additional packages, like the aws-sdk package.