alexziskind1 / nativescript-oauth2

Other
86 stars 93 forks source link

Login with ios the url is Website name #115

Open ghost opened 4 years ago

ghost commented 4 years ago

Hello everyone,

I have a problem with logging in to IOS on identity server 4. Everything worked fine so far, but for some time when login IOS instead of the url it reports Website name. With android everything works ok. I haven't changed anything since before. Furthermore, when I logout from IOS and Android, it often returns to the login page of my App and not to the logout page of identity server 4, allowing the user to login again without entering the user and password.

Can anyone help me?

Schermata 2020-05-11 alle 15 00 26

My Package.json

"nativescript": { "id": "xxx.xx.xxxxxxxx", "tns-android": { "version": "6.5.0" }, "tns-ios": { "version": "6.5.0" } }, "dependencies": { "@angular/animations": "^8.2.14", "@angular/common": "^8.2.14", "@angular/compiler": "^8.2.14", "@angular/core": "^8.2.14", "@angular/forms": "^8.2.14", "@angular/http": "8.0.0-beta.10", "@angular/platform-browser": "^8.2.14", "@angular/platform-browser-dynamic": "^8.2.14", "@angular/router": "^8.2.14", "decode-google-map-polyline": "^1.0.1", "jwt-decode": "^2.2.0", "moment": "^2.24.0", "nativescript-angular": "^8.21.0", "nativescript-directions": "^1.3.1", "nativescript-geolocation": "^5.1.0", "nativescript-google-maps-sdk": "^2.9.1", "nativescript-keyboard-toolbar": "^1.1.0", "nativescript-oauth2": "^2.4.0", "nativescript-pager": "^12.0.0-alpha.8", "nativescript-permissions": "^1.3.8", "nativescript-signalr-core": "^1.0.12", "nativescript-theme-core": "^2.0.24", "nativescript-ui-calendar": "^6.1.0", "nativescript-ui-listview": "^8.0.1", "nativescript-ui-sidedrawer": "^8.0.1", "nativescript-websockets": "^1.5.5", "reflect-metadata": "~0.1.13", "rxjs": "^6.5.4", "tns-core-modules": "^6.5.1", "tns-platform-declarations": "^6.5.1", "zone.js": "^0.10.2" }, "devDependencies": { "@angular/compiler-cli": "8.2.0", "@ngtools/webpack": "^9.0.2", "nativescript-dev-appium": "^6.1.3", "nativescript-dev-webpack": "^1.4.1", "node-sass": "~4.13.1", "typescript": "~3.5.3" }

login.component.ts

public onTapLogin() {
    this.authService
        .tnsOauthLogin("identityServer")
        .then((result: ITnsOAuthTokenResult) => {
            console.log("back to login component with token " + result.accessToken);
            this.routerExtension
                .navigate(["../tabs/default"], { clearHistory: true })
                .then(() => this.routerExtension.navigate(["../tabs/default"], { clearHistory: true}))
                .catch(err => console.log("error navigating to /authenticated: " + err));
        })
        .catch(e => console.log("Error: " + e));

}

auth-providers-helper.ts

export function configureOAuthProviderIdentityServer(): TnsOaProvider { const identityServerProviderOptions: TnsOaProviderOptionsIdentityServer = { openIdSupport: 'oid-full', issuerUrl: 'https://xxxx-xxxx.xxxxx.xx/xxxxxxx-5328-4f3c-9909-c7203e660458', clientId: 'xxxxxxxxxxx_ns', urlScheme: 'xxx.xxx.votodigitale', redirectUri: 'xxx.xxx.votodigitale://auth', scopes: ['openid', 'profile', 'roles', 'votazionedigitale', 'asfappusers', 'offline_access', 'asfappprofile', 'asfappcore'] }; const identityServerProvider = new TnsOaProviderIdentityServer( identityServerProviderOptions ); return identityServerProvider; }

auth.service.ts

import { Injectable, NgZone } from "@angular/core"; import { HttpClient } from "@angular/common/http"; import { TnsOAuthClient, ITnsOAuthTokenResult } from "nativescript-oauth2"; import { AuthTokenService } from "./auth-token.service"; import { AuthUserService } from "./auth-user.service"; import { PtUser } from "../models/domain/pt-user.model"; import { StorageNsService } from "./ns/storage-ns.service"; import { Store } from "../state/app-store"; import * as jwt_decode from 'jwt-decode';

const CURRENT_USER_KEY = 'CURRENT_USER_KEY';

@Injectable() export class AuthService {

private client: TnsOAuthClient = null;

public get currentUser(): PtUser { const user = this.storageService.getItem(CURRENT_USER_KEY); if (!this.store.value.currentUser && user) { this.store.set('currentUser', user); } return user; }

public set currentUser(ptUser: PtUser) { this.storageService.setItem(CURRENT_USER_KEY, ptUser); this.store.set('currentUser', ptUser); }

constructor(private http: HttpClient, private authTokenService: AuthTokenService, private authUserService: AuthUserService, private storageService: StorageNsService, private store: Store, private zone: NgZone ) { }

public tnsOauthLogin(providerType): Promise { this.client = new TnsOAuthClient(providerType);

return new Promise<ITnsOAuthTokenResult>((resolve, reject) => {
  this.zone.run(() => {
    this.client.loginWithCompletion(
      (tokenResult: ITnsOAuthTokenResult, error) => {
        if (error) {
          console.error("back to main page with error: ");
          console.error(error);
          reject(error);
        } else {
          var decoded = jwt_decode(tokenResult.accessToken);
          console.log("back to main page with access token: ");
          console.log(tokenResult);
          var myObject = {} as PtUser;
          myObject.userid = decoded.UserId;
          myObject.fiscalCode = decoded.FiscalCode;
          myObject.email = decoded.preferred_username;
          this.currentUser = myObject;
          this.setToken(tokenResult.accessToken);
          this.setUserId(decoded.UserId);
          this.setExpiration(decoded.exp);
          resolve(tokenResult);
        }
      }
    );
  });
});

}

public tnsOauthRefreshToken = (): void => { if (!this.client) { return; } this.zone.run(() => { this.client.refreshTokenWithCompletion((tokenResult: ITnsOAuthTokenResult, error) => { if (error) { console.error("Unable to refresh token with error: "); console.error(error); } else { console.log("Successfully refreshed access token: "); console.log(tokenResult); this.setToken(tokenResult.accessToken); } }); });

}

public tnsOauthLogout(): Promise { return new Promise((resolve, reject) => { if (this.client) { this.zone.run(() => { this.client.logoutWithCompletion( (error) => { if (error) { console.error("back to main page with error: "); console.error(error); reject(error); } else { console.log("back to main page with success"); resolve(); } } ); }); } else { console.log("back to main page with success"); resolve(); } }); }

public isLoggedIn(): boolean { const expires = this.authTokenService.expiration; if (!expires) { return false; } return new Date().getTime() < expires; }

public setExpiration = (expires: number): void => { this.authTokenService.expiration = expires; }

public setToken = (accessToken: string): void => { this.authTokenService.token = accessToken; }

public getToken(): string { return this.authTokenService.token; }

public setUserId = (userid: string): void => { this.authTokenService.userId = userid; }

public getUserId(): string { return this.authTokenService.userId; }

private setUser(user: PtUser): void { this.authUserService.userStore = user; }

public getUser(): PtUser { return this.authUserService.userStore; }

}

mpht commented 4 years ago

Hi there! If understood correctly everything works fine on Android but on iOS it does not work anymore? I assume you have not touched the auth part of you app but you have changed layout/other stuff not directly related to auth recently?

Could it be that your issue is related to #116

When you try to login on iOS and check the logs. Do you find: Presenting view controllers on detached view controllers is discouraged

best regards, mp

ghost commented 4 years ago

Hi,

I applied the changes described in #116 , it works.

I still have the problem when I logout from IOS and Android, it often returns to the login page of my App and not to the logout page of identity server 4, allowing the user to login again without entering the user and password.

I use nested router outlets.

app-routing.module.ts

`import { NgModule } from "@angular/core"; import { NativeScriptRouterModule } from "nativescript-angular/router"; import { Routes } from "@angular/router";

import { LoginComponent } from "./login/login.component"; import { WelcomeComponent } from "./welcome/welcome.component"; import { AuthGuard } from "./core/services/auth-guard.service";

export const COMPONENTS = [LoginComponent, WelcomeComponent];

const routes: Routes = [ { path: "", redirectTo: "/tabs/default", pathMatch: "full" }, { path: "login", component: LoginComponent }, { path: "welcome", component: WelcomeComponent }, { path: "tabs", loadChildren: "~/app/tabs/tabs.module#TabsModule", canActivate: [AuthGuard] }, ];

@NgModule({ imports: [NativeScriptRouterModule.forRoot(routes, { enableTracing: true })], exports: [NativeScriptRouterModule], }) export class AppRoutingModule { }`

app.component.html

`

            <StackLayout class="hr"></StackLayout>
            <GridLayout rows="auto, auto" columns="*" class="sidedrawer-list-item" title="Friends"
                tap="onNavigationItemTap">
                <Label row="0" col="0" text="&#xf783;" class="fal sidedrawer-icon"></Label>
                <Label row="1" col="0" text="Agenda sedute" class="sidedrawer-item"></Label>
            </GridLayout>
            <StackLayout class="hr"></StackLayout>
            <GridLayout rows="auto, auto" columns="*" class="sidedrawer-list-item" title="Friends"
                tap="onNavigationItemTap">
                <Label row="0" col="0" text="&#xf007;" class="fal sidedrawer-icon"></Label>
                <Label row="1" col="0" text="Profilo" class="sidedrawer-item"></Label>
            </GridLayout>
            <StackLayout class="hr"></StackLayout>
        </StackLayout>
    </ScrollView>
    <StackLayout row="2" class="sidedrawer-footer">
        <GridLayout rows="auto, auto" columns="*" class="sidedrawer-list-item" title="Friends"
            (tap)="onTapLogout()">
            <Label row="0" col="0" text="&#xf08b;" class="fal sidedrawer-icon"></Label>
            <Label row="1" col="0" text="Logout" class="sidedrawer-item"></Label>
        </GridLayout>
    </StackLayout>
</GridLayout>
<GridLayout tkMainContent>
    <page-router-outlet actionBarVisibility="never"></page-router-outlet>
</GridLayout>

`

Which platform(s) does your issue occur on? iOS

Please, provide the following version numbers that your issue occurs with: 6.5.0

Cross-platform modules: tns-core-modules@^6.5.1

Runtime(s):

"tns-android": {
  "version": "6.5.0"
},
"tns-ios": {
  "version": "6.5.0"
}

best regards, dp