Open yuriygavriluk opened 10 months ago
Hello @yuriygavriluk . Can you attach the /
at the end of your sign-in/out redirect e.g
{
signInRedirect: 'https://showcase.grorain.com/' ,
signOutRedirect: 'https://showcase.grorain.com/'
}
Hello @israx Changed to "redirectSignIn": "https://showcase.grorain.com/", "redirectSignOut": "https://showcase.grorain.com/",
in both amplifyconfiguration.json and aws-exports.js
did not make any difference currently hosted here https://showcase.grorain.com/
if you have any other ideas to try please let me know
Added log of the state
<div>
<div>
authStatus: {{authenticator.authStatus}}
</div>
<!-- Render loading if authStatus is still configuring -->
<ng-container *ngIf="authenticator.authStatus === 'configuring'">
Loading...
</ng-container>
<!-- Only render this if there's an authenticated user -->
<ng-container *ngIf="authenticator.authStatus === 'authenticated'">
Welcome back!
</ng-container>
<!-- Render sign-in screen otherwise with authenticator -->
<ng-container *ngIf="authenticator.authStatus !== 'authenticated'">
<amplify-authenticator></amplify-authenticator>
</ng-container>
</div>
it seems like state is not being updated
import { Component } from '@angular/core'; import { AuthenticatorService } from '@aws-amplify/ui-angular';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'ang-showcase-app';
constructor(public authenticator: AuthenticatorService) {
}
}
@yuriygavriluk, after looking into this further... we've confirmed that this looks to be working as expected on the amplify-js
side of things. This appears to be an issue associated with the Authenticator, so i'll send this over to the amplify-ui
repo to get better assistance! Appreciate your patience on this.
Hi @yuriygavriluk. Have been unable to repro the issue based off the code example you provided. Where are you calling Amplify.configure
?
Hello @calebpollman Thanks for your reply main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { Amplify } from 'aws-amplify';
import amplifyconfig from './amplifyconfiguration.json';
Amplify.configure(amplifyconfig);
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
Curretnly simple hosted solution can be checked here https://showcase.grorain.com/
And and just does not work smooth So once you have empy page you can to reload (f5 in browser) and you are being logged in properly And also please note that this does not work only with Facebook or Gmail in case you work with user from user pool it works as expected
Please do let me know if any other useful info I can provide
To isolate whether the issue may be with the application configuration can you verify that the post sign in redirect is working as expected without the authenticator
element?
Here is some example code with the signWithRedirect
function used internally by the authenticator
// sign-in-federated.component.ts
import { Component } from '@angular/core';
import {
fetchAuthSession,
signInWithRedirect,
signOut,
} from 'aws-amplify/auth';
@Component({
selector: 'sign-in-federated',
templateUrl: 'sign-in-federated.component.html',
})
export class SignInFederatedComponent {
public isSignedIn = false;
constructor() {
this.fetchAuthSession();
}
async fetchAuthSession() {
try {
await fetchAuthSession();
this.isSignedIn = true;
} catch {
// `fetchAuthSession` throws if no current session
}
}
public signInWithRedirect() {
// 'Google` can be swapped out with other configured providers (example: 'Facebook')
signInWithRedirect({ provider: 'Google' });
}
public signOut() {
signOut();
this.isSignedIn = false;
}
}
<!-- sign-in-federated.component.html -->
<div>
<p>Signed In? {{ isSignedIn }}</p>
<ng-container *ngIf="!isSignedIn">
<button (click)="signInWithRedirect()">Sign In!</button>
</ng-container>
<ng-container *ngIf="isSignedIn">
<button (click)="signOut()">Sign Out!</button>
</ng-container>
</div>
this is deployed example
For me it is hard to say whether it works or not as there's no state difference between logged in use and not logged in as in original request Feel free to explore on my site it is for testing purposes
if we can add some state on ui e.g. label user is logged in or not and his name that would be very cool to check
@yuriygavriluk Totally valid request. Updated the example code here to conditionally render the sign in/out buttons and provide whether there is a signed in user
Same issue After log in state is not updated if I do page reload it starts working properly
@yuriygavriluk Got it. As you were able to repro the issue without using the authenticator
it seems likely that the issue is in your application setup. Going to route this issue back to Amplify JS for further triage
I will now try to use react To see if it makes difference or not This will naswer if the issue in JS or not
@yuriygavriluk, let's see if we can get you unblocked here then if it doesn't seem to be a bug in the JS library or the UI side with the authenticator. If you still experience the issue with React, definitely comment back and let us know.
react sample works just fine https://showcase.grorain.com/
simple code
<Authenticator>
{({ signOut, user }) => (
<main>
<h1>Hello {user.username}</h1>
<button onClick={signOut}>Sign out</button>
</main>
)}
</Authenticator>
After being rediected see proper state
For me sounds like something wrong with Angular packages and state is not managed properly for some reason
Just wanted to point that still not clear how to use it in Anguar project
Using react is an option but can be too big change in some cases
hello @yuriygavriluk . Just wanted to confirm, this seems to be specific to the Angular authenticator. Did you use the same amplify config on the React Authenticator ?
Could you call the signInWithRedirect
API in your Angular App, without the Angular Authenticator, and see if you are able authenticate ?
Hello @israx thanks for your reply config is the same
so only angular vs react was changed
signInWithRedirect we did this experiment and it behaves the same as Angular Authenticator so the same problem
is this only with Angular Authenticator -- no
signInWithRedirect this method is also used by react behind the scenes?
I think some Angular versions don't re-render components on window redirect, thus not calling any APIs that allow to verify the user is authenticated, is it possible for you to listen to the signInWithRedirect
hub event and then update state as desired ?
Not too sure what this means but all the code is very simple and was provided here on the comments
I can run the solution again if you want to check
But to sum this method signinwithredirect works for some anguar versions and facebook or gmail correct?
I'm not sure about Angular versions but I noticed some Angular Apps don't re-render components after being redirected from signInWithRedirect
API, my suggestion is to try listening for the signInWithRedirect
Hub event and then updating your state as desired.
Thanks a lot for explanation Will try And message
please do and let's us know
Added this hub listener In this configuration with component does not write any message current code is hosted here https://showcase.grorain.com/
import { Component } from '@angular/core';
import {
fetchAuthSession,
signInWithRedirect,
signOut,
} from 'aws-amplify/auth';
import { Hub } from 'aws-amplify/utils';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'ang-showcase-app';
public isSignedIn = false;
constructor() {
Hub.listen('auth', this.listener);
this.fetchAuthSession();
}
listener = (data: any) => {
console.log('Data---');
console.log(data);
};
async fetchAuthSession() {
try {
await fetchAuthSession();
this.isSignedIn = true;
} catch {
// `fetchAuthSession` throws if no current session
}
}
public signInWithRedirect() {
// 'Google` can be swapped out with other configured providers (example: 'Facebook')
signInWithRedirect({ provider: 'Google' });
}
public signOut() {
signOut();
this.isSignedIn = false;
}
}
Thank you for the reproducible code, is it possible to listen for the signInWithRedirect
hub event and then call this.isSignedIn = true
. E.g
listener = (data: any) => {
console.log('Data---');
console.log(data);
switch(data.payload.event){
'signInWithRedirect':
this.isSignedIn = true
break
}
};
this code is not hit //console.log('Data---'); this is never logged
I'm able to log the actual data based on your app. I'm running it on the latest version of Chrome.
Yes my mistake Thanks
Added code above still have issues
cannot updated state in that call back from some reason
it may seem that rendering does not work but if I press new button 'Test rendering' value is being changed
Adding code
import { Component } from '@angular/core';
import {
fetchAuthSession,
signInWithRedirect,
signOut,
} from 'aws-amplify/auth';
import { Hub } from 'aws-amplify/utils';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'ang-showcase-app';
public isSignedIn = false;
public anotherMessage = '';
constructor() {
Hub.listen('auth', this.listener);
this.fetchAuthSession();
}
listener = (data: any) => {
console.log('Data---');
console.log(data);
switch (data.payload.event) {
case 'signInWithRedirect':
this.isSignedIn = true;
this.anotherMessage = 'new message';
console.log('setting values ' +
JSON.stringify({
isSignedIn: this.isSignedIn,
anotherMessage: this.anotherMessage
})
);
break
}
};
async fetchAuthSession() {
try {
await fetchAuthSession();
this.isSignedIn = true;
} catch {
// `fetchAuthSession` throws if no current session
}
}
setTestValueTestAngularRendering() {
this.anotherMessage = 'testing rendeting';
}
public signInWithRedirect() {
// 'Google` can be swapped out with other configured providers (example: 'Facebook')
signInWithRedirect({ provider: 'Google' });
}
public signOut() {
signOut();
this.isSignedIn = false;
}
}
@yuriygavriluk, wanted to check in and see if you've figured out what's causing this yet. If not, have you tried using the ChangeDetectorRef
class that @angular/core
provides?
To @israx's comment above, I'm wondering if the state of the app after the Auth redirect flow doesn't have the proper context/data being returned after signing in. Can you see if refactoring your code to include this class and the detectChanges()
method it provides help resolve the issue?
Note - I've also added a couple of async/awaits because signOut()
and signInWithRedirect()
both return a promise.
import { Component, ChangeDetectorRef } from '@angular/core';
import {
fetchAuthSession,
signInWithRedirect,
signOut,
} from 'aws-amplify/auth';
import { Hub } from 'aws-amplify/utils';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'ang-showcase-app';
public isSignedIn = false;
public anotherMessage = '';
constructor(private changeDetectorRef: ChangeDetectorRef) {
Hub.listen('auth', this.listener);
this.fetchAuthSession();
}
listener = (data: any) => {
console.log('Data---');
console.log(data);
switch (data.payload.event) {
case 'signInWithRedirect':
this.isSignedIn = true;
this.anotherMessage = 'new message';
console.log('setting values ' +
JSON.stringify({
isSignedIn: this.isSignedIn,
anotherMessage: this.anotherMessage
})
);
this.changeDetectorRef.detectChanges();
break;
}
};
async fetchAuthSession() {
try {
await fetchAuthSession();
this.isSignedIn = true;
this.changeDetectorRef.detectChanges();
} catch {
// `fetchAuthSession` throws if no current session
}
}
setTestValueTestAngularRendering() {
this.anotherMessage = 'testing rendering';
this.changeDetectorRef.detectChanges();
}
public async signInWithRedirect() {
// 'Google` can be swapped out with other configured providers
await signInWithRedirect({ provider: 'Google' });
}
public async signOut() {
await signOut();
this.isSignedIn = false;
// Manually trigger change detection to update the view
this.changeDetectorRef.detectChanges();
}
}
@cwomack I confirm the code you provided works as expected State login\logout changed without any neccessety of extra reloading page Thanks a lot
Will check with the original code
I will check the original code if this works or not perhapse it will help to localyze the issue
and coming back to the original sample from the doc app.component.html `
<ng-container *ngIf="authenticator.authStatus === 'configuring'"> Loading...
<ng-container *ngIf="authenticator.authStatus === 'authenticated'"> Welcome back!
<ng-container *ngIf="authenticator.authStatus !== 'authenticated'">
app.component.ts `import { Component } from '@angular/core'; import { AuthenticatorService } from '@aws-amplify/ui-angular';
@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { title = 'ang-showcase-app'; constructor(public authenticator: AuthenticatorService) { } } `
app.module.ts `import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component'; import { AmplifyAuthenticatorModule } from '@aws-amplify/ui-angular'; import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import {MatToolbarModule} from '@angular/material/toolbar'; import {MatButtonModule} from '@angular/material/button';
@NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AmplifyAuthenticatorModule, MatSlideToggleModule, BrowserAnimationsModule, MatToolbarModule, MatButtonModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } `
main.ts `import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { Amplify } from 'aws-amplify'; import amplifyconfig from './amplifyconfiguration.json'; Amplify.configure(amplifyconfig);
platformBrowserDynamic().bootstrapModule(AppModule) .catch(err => console.error(err)); `
In this sample I can login using cognito user (the one that was created manually) all works as expected Neither facebook nor gmail does not work properly requires page reload to get proper state
And page reload will fix the issue
If you just have any ideas how I can patch the code so that it works properly that would be nice or I can use workaround we discussed before just a bit more code
Thanks for help
Hello @yuriygavriluk . Can you confirm that the sample code suggested by @cwomack ended up working ? And that you are still attempting to use the UI Authenticator without having any results yet? If that is the case, there might be a bug in the Authenticator, and we would need to transfer this issue to the UI team for better assistance.
HI @israx I confirm this code works as expected https://github.com/aws-amplify/amplify-ui/issues/5048
Original code does not work https://github.com/aws-amplify/amplify-ui/issues/5048
so @cwomack suggestion can be used as workaround for sure
@yuriygavriluk, glad you've got a workaround now at least! It sounds like this may need some further investigation from the amplify-ui
team to determine if there's a feature request related to the change detection with Angular in particular.
Going to cc: @calebpollman and transfer the issue back to that repo for next/final steps on this issue.
Before opening, please confirm:
JavaScript Framework
Angular
Amplify APIs
Authentication
Amplify Version
v6
Amplify Categories
No response
Backend
Amplify CLI
Environment information
System: OS: Windows 11 10.0.22621 CPU: (8) x64 Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz Memory: 4.91 GB / 15.78 GB Binaries: Node: 18.16.1 - C:\Program Files\nodejs\node.EXE npm: 9.5.1 - C:\Program Files\nodejs\npm.CMD Browsers: Edge: Chromium (120.0.2210.133) Internet Explorer: 11.0.22621.1 npmPackages: @angular-devkit/build-angular: ^16.1.0 => 16.2.11 @angular/animations: ^16.1.0 => 16.2.12 @angular/cdk: ^16.2.12 => 16.2.12 @angular/cli: ~16.1.0 => 16.1.8 @angular/common: ^16.1.0 => 16.2.12 @angular/compiler: ^16.1.0 => 16.2.12 @angular/compiler-cli: ^16.1.0 => 16.2.12 @angular/core: ^16.1.0 => 16.2.12 @angular/forms: ^16.1.0 => 16.2.12 @angular/material: ^16.2.12 => 16.2.12 @angular/platform-browser: ^16.1.0 => 16.2.12 @angular/platform-browser-dynamic: ^16.1.0 => 16.2.12 @angular/router: ^16.1.0 => 16.2.12 @aws-amplify/cli: ^12.10.1 => 12.10.1 @aws-amplify/ui-angular: ^5.0.6 => 5.0.6 @types/jasmine: ~4.3.0 => 4.3.6 aws-amplify: ^6.0.11 => 6.0.11 aws-amplify/adapter-core: undefined () aws-amplify/analytics: undefined () aws-amplify/analytics/kinesis: undefined () aws-amplify/analytics/kinesis-firehose: undefined () aws-amplify/analytics/personalize: undefined () aws-amplify/analytics/pinpoint: undefined () aws-amplify/api: undefined () aws-amplify/api/server: undefined () aws-amplify/auth: undefined () aws-amplify/auth/cognito: undefined () aws-amplify/auth/cognito/server: undefined () aws-amplify/auth/enable-oauth-listener: undefined () aws-amplify/auth/server: undefined () aws-amplify/datastore: undefined () aws-amplify/in-app-messaging: undefined () aws-amplify/in-app-messaging/pinpoint: undefined () aws-amplify/push-notifications: undefined () aws-amplify/push-notifications/pinpoint: undefined () aws-amplify/storage: undefined () aws-amplify/storage/s3: undefined () aws-amplify/storage/s3/server: undefined () aws-amplify/storage/server: undefined () aws-amplify/utils: undefined () jasmine-core: ~4.6.0 => 4.6.0 karma: ~6.4.0 => 6.4.2 karma-chrome-launcher: ~3.2.0 => 3.2.0 karma-coverage: ~2.2.0 => 2.2.1 karma-coverage-coffee-example: 1.0.0 karma-jasmine: ~5.1.0 => 5.1.0 karma-jasmine-html-reporter: ~2.1.0 => 2.1.0 rxjs: ~7.8.0 => 7.8.1 rxjs/ajax: undefined () rxjs/fetch: undefined () rxjs/operators: undefined () rxjs/testing: undefined () rxjs/webSocket: undefined () tslib: ^2.3.0 => 2.6.2 (2.6.1, 1.14.1) typescript: ~5.1.3 => 5.1.6 zone.js: ~0.13.0 => 0.13.3 npmGlobalPackages: @angular/cli: 16.1.0 @aws-amplify/cli: 12.10.0 aws-cdk: 2.108.1 serverless: 3.34.0
Describe the bug
Using this sample https://ui.docs.amplify.aws/angular/connected-components/authenticator/advanced Access Auth State
This code works perfectly fine when login in with users from user pool
When I run social login and login via facebook or gmail
does not work properly
it requires page refresh to see the content if I only aprove it on FB and go further see blank screen by default
Expected behavior
f5 in browser is shuold not be required to see content in single page application after logging in via social links
Reproduction steps
<ng-container *ngIf="authenticator.authStatus === 'authenticated'"> Welcome back!
<ng-container *ngIf="authenticator.authStatus !== 'authenticated'">
Log output
<ng-container *ngIf="authenticator.authStatus === 'configuring'"> Loading...
<ng-container *ngIf="authenticator.authStatus === 'authenticated'"> Welcome back!
<ng-container *ngIf="authenticator.authStatus !== 'authenticated'">
aws-exports.js
/ eslint-disable / // WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.
const awsmobile = { "aws_project_region": "*", "aws_cognito_identity_pool_id": "**", "aws_cognito_region": "*", "aws_user_pools_id": "", "aws_user_pools_web_client_id": "", "oauth": { "domain": "***", "scope": [ "phone", "email", "openid", "profile", "aws.cognito.signin.user.admin" ], "redirectSignIn": "https://showcase.grorain.com", "redirectSignOut": "https://showcase.grorain.com", "responseType": "code" }, "federationTarget": "COGNITO_USER_POOLS", "aws_cognito_username_attributes": [], "aws_cognito_social_providers": [ "FACEBOOK", "GOOGLE" ], "aws_cognito_signup_attributes": [ "EMAIL", "GIVEN_NAME" ], "aws_cognito_mfa_configuration": "OFF", "aws_cognito_mfa_types": [ "SMS" ], "aws_cognito_password_protection_settings": { "passwordPolicyMinLength": 6, "passwordPolicyCharacters": [ "REQUIRES_LOWERCASE" ] }, "aws_cognito_verification_mechanisms": [ "EMAIL" ] };
export default awsmobile;
Manual configuration
No response
Additional configuration
No response
Mobile Device
No response
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Additional information and screenshots
No response