javascript - Auth0 与 Angular 4 登录错误

标签 javascript angular authentication auth0

我尝试登录时遇到问题。一步一步:

- 用户点击登录按钮;
- Auth0 似乎执行登录;
- 用户个人资料保存在localStorage中;
- 登录成功后,将加载内部页面,用户可以使用系统。每个页面都需要配置文件数据(在 localStorage 中)。

问题

首次登录无法进入系统。它是空的!!!即使登录成功!我设置了一个流程,当 localStorage 为空时注销系统,因此它会重定向到登录页面。 但是当你再次尝试时,一切都会顺利!我不知道为什么。

遵循代码。

AuthService

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { ApiService } from './api.service';
import { Profile } from '../models/Profile';
import auth0 from 'auth0-js';
import 'rxjs/add/operator/filter';

@Injectable()
export class AuthService {
    auth0 = new auth0.WebAuth({
        // Credentials
    });

    constructor(protected router: Router, protected api: ApiService) {}

    public login(): void {
        this.auth0.authorize();
    }

    public logout(): void {
        localStorage.removeItem('profile');
        localStorage.removeItem('id_token');
        localStorage.removeItem('expires_at');
        localStorage.removeItem('access_token');
        this.router.navigate(['/']);
    }

    private setSession(authResult): void {
        const profile = authResult.idTokenPayload;
        const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
        localStorage.setItem('expires_at', expiresAt);
        localStorage.setItem('id_token', authResult.idToken);
        localStorage.setItem('access_token', authResult.accessToken);
        this.api.getUsuario(profile.name)
        .subscribe(res => {
            profile.nivel = res.nivel;
            profile.idClube = res.idClube;
            localStorage.setItem('profile', JSON.stringify(profile));
        });
    }

    public handleAuthentication(): void {
        this.auth0.parseHash((err, authResult) => {
            if (authResult && authResult.accessToken && authResult.idToken) {
                window.location.hash = '';
                this.setSession(authResult);
                this.router.navigate(['/calendario_']);
            } else if (err) {
                this.router.navigate(['/login']);
                console.error(err);
            }
        });
    }

    public isAuthenticated(): boolean {
        const expiresAt = JSON.parse(localStorage.getItem('expires_at'));
        return new Date().getTime() < expiresAt;
    }
}


登录组件

import { Component } from '@angular/core';
import { AuthService } from '../../services/auth.service';

@Component({
    moduleId: module.id,
    selector: 'app-login',
    templateUrl: './login.component.html',
    styleUrls: ['./login.component.css']
})

export class LoginComponent {
    constructor(protected auth: AuthService) { }
}


组件(成功登录后)

import { Component, OnInit } from '@angular/core';

import { Profile } from '../../models/Profile';
import { Calendario } from '../../models/Calendario';
import { ApiService } from '../../services/api.service';
import { AuthService } from '../../services/auth.service';

@Component({
    moduleId: module.id,
    selector: 'app-calendarioproximo',
    templateUrl: './calendarioProximo.component.html'
})

export class CalendarioProximoComponent implements OnInit {

protected title: string;
protected dataAtual: any;
protected loading = true;
protected profile: Profile;
protected model: Calendario[] = [];
protected calendario: Calendario[] = [];

constructor(protected api: ApiService, protected auth: AuthService) { }

getCalendario() {
    this.api.getCalendario(this.profile.idClube)
    .subscribe(res => {
        this.loading = true;
        this.model = res;
        this.api.getData()
        .subscribe(data => {
            this.dataAtual = data.dataCompleta;
            for (let cont = 0; cont < this.model.length && this.calendario.length < 5; cont++) {
                if (this.model[cont].data >= this.dataAtual) {
                this.calendario[this.calendario.length] = this.model[cont];
                }
            }
            this.loading = false;
        }, err => console.error(err));
    });
}

ngOnInit() {
    this.title = 'Calendário Próximo';
    this.profile = new Profile();
    // HERE!
    JSON.parse(localStorage['profile']) ? this.profile = JSON.parse(localStorage['profile']) : this.auth.logout();
    this.getCalendario();
    window.scrollTo(0, 0);
    }
}

最佳答案

您的setSession(authResult)函数不保存profile同时保存expires_at , id_token ,和access_token .

分配最终会发生,作为处理程序的一部分

getUsuario(profile.name).subscribe(() => {...})`.
<小时/>

搬家this.router.navigate(['/calendario_']);来自handleAuthentication进入setSession可以解决您的问题:

private setSession(authResult): void {
    const profile = authResult.idTokenPayload;
    const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
    localStorage.setItem('expires_at', expiresAt);
    localStorage.setItem('id_token', authResult.idToken);
    localStorage.setItem('access_token', authResult.accessToken);
    this.api.getUsuario(profile.name)
    .subscribe(res => {
        profile.nivel = res.nivel;
        profile.idClube = res.idClube;
        localStorage.setItem('profile', JSON.stringify(profile));

        this.router.navigate(['/calendario_']);   // Navigate after you `profile` has been set for sure
    });
}

public handleAuthentication(): void {
    this.auth0.parseHash((err, authResult) => {
        if (authResult && authResult.accessToken && authResult.idToken) {
            window.location.hash = '';
            this.setSession(authResult);

            // this.router.navigate(['/calendario_']);   // This is too early...
        } else if (err) {
            this.router.navigate(['/login']);
            console.error(err);
        }
    });
}

关于javascript - Auth0 与 Angular 4 登录错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46901878/

相关文章:

javascript - Html Checkbox,多个具有相同的 'name' 。如果选中,值为 1,如果未选中,值为 0

javascript - 带有 npm 的客户端 Prism.js

css - 如何更改单个垫子图标的背景颜色?

html - Bootstrap 类未按预期工作

angular - 您如何在 ngOnInit 生命周期中测试可观察对象?

javascript - 如何为按钮设置图像和为图像设置悬停效果

authentication - 如何验证以查看 mongodb 的 http 控制台?

java - TargetAuthenticationStrategy,更改优先顺序

c# - 没有身份验证处理程序配置为验证方案 : Microsoft. AspNet.Identity.External

javascript - Jquery,从下拉列表中删除选项不起作用