Categorías
Python

Módulo pathlib de Python 3: La doma del sistema de archivos

 

Tabla de contenidos Configuración

    Proyecto

  • de autenticación de flujo de trabajo
  • componente Auth
  • Bootstrap Estilo
  • de autenticación ServiceSanity CheckUser LoginUser Registro
  • cordura Compruebe
  • usuario Iniciar sesión
  • Registro de Usuario
  • de configuración del lado del servidor
  • cordura Comprobar de
  • de autenticación de sesión de autenticación
  • Registro
  • Almacenamiento local
  • Condición de usuario
  • Ruta Restricción
  • ¿Qué sigue?
  • cordura Compruebe
  • usuario Iniciar sesión
  • Registro de Usuario

En este tutorial, vamos a demostrar cómo configurar la autenticación basada en token (vía web JSON Tokens) con 4 angular y el frasco.

principal Dependencias : Bonus

gratuito: Haga clic aquí para obtener acceso a un tutorial de vídeo gratuito + Frasco Python que muestra cómo construir aplicación web Frasco, paso a paso.

de autenticación de flujo de trabajo

Aquí está el proceso de autenticación de usuario completa: Configuración del Proyecto

de inicio mediante la instalación a nivel mundial el angular de la CLI:

$ npm install -g @angular/cli@1.3.2

luego generar una nueva angular repetitivo 4 proyectos:

$ ng new angular4-auth

fuego de la aplicación después de las dependencias instalan :

$ cd angular4-auth
$ ng serve

es probable que tome un minuto o dos para compilar y construir su aplicación. Una vez hecho esto, vaya a http: // localhost: 4200 para garantizar la aplicación está en funcionamiento.

Abrir el proyecto en el editor de código favorito, y luego mirar por encima del código:

├── e2e
│   ├── app.e2e-spec.ts
│   ├── app.po.ts
│   └── tsconfig.e2e.json
├── karma.conf.js
├── package.json
├── protractor.conf.js
├── src
│   ├── app
│   │   ├── app.component.css
│   │   ├── app.component.html
│   │   ├── app.component.spec.ts
│   │   ├── app.component.ts
│   │   └── app.module.ts
│   ├── assets
│   ├── environments
│   │   ├── environment.prod.ts
│   │   └── environment.ts
│   ├── favicon.ico
│   ├── index.html
│   ├── main.ts
│   ├── polyfills.ts
│   ├── styles.css
│   ├── test.ts
│   ├── tsconfig.app.json
│   ├── tsconfig.spec.json
│   └── typings.d.ts
├── tsconfig.json
└── tslint.json

En resumen, el código del lado del cliente vive en la carpeta “src” y la propia aplicación angular se puede encontrar en la “aplicación” carpeta.

Tomar nota de la AppModule dentro app.module.ts . Esto se utiliza para arrancar la aplicación angular. El decorador @NgModule toma metadatos que hace saber angular cómo ejecutar la aplicación. Todo lo que creamos en este tutorial se añadirá a este objeto.

Asegúrate de que tienes una idea decente de la estructura de aplicación antes de continuar.

NOTA: acaba de empezar con 4 angular? Revisar la Guía de estilo angular, ya que la aplicación generada a partir de la CLI sigue la estructura recomendada de esa guía, así como el Tutorial Angular4Crud.

¿Notaste que la CLI inicializar un nuevo repositorio git? Esta parte es opcional, pero es una idea buena para crear un nuevo repositorio Github y actualizar el control remoto:

$ git remote set-url origin

Ahora, vamos a cable hasta un nuevo componente …

componente Auth

primer lugar, utilice la CLI para generar un nuevo componente de sesión :

$ ng generate component components/login

Esto creó los archivos y carpetas de componentes e incluso cableado que hasta app.module.ts . A continuación, vamos a cambiar el login.component.ts archivo a lo siguiente:

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

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

export class LoginComponent {
test: string = 'just a test';
}

Si usted no ha utilizado mecanografiado antes, entonces este código, probablemente, se ve bastante extraño para ti. Letra de imprenta es un superconjunto de tipo estático de JavaScript que se compila a JavaScript básico, y es el lenguaje de programación de facto para la construcción angular 4 aplicaciones.

En angular 4, se define un componente envolviendo un objeto de configuración con un decorador de @Component. Podemos compartir código entre los paquetes mediante la importación de las clases que necesitamos; y, en este caso, importamos componentes del paquete @ angular / núcleo. La clase LoginComponent es el controlador de componente ‘s, y usamos el operador de exportación para que esté disponible para otras clases a la importación.

Añadir el siguiente código HTML en el login.component.html :

Login

{{test}}

A continuación, configure las rutas, a través de la RouterModule en el app.module.ts archivo :

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';

import { AppComponent } from './app.component';
import { LoginComponent } from './components/login/login.component';

@NgModule({
declarations: [
AppComponent,
LoginComponent,
],
imports: [
BrowserModule,
RouterModule.forRoot([
{ path: 'login', component: LoginComponent }
])
],
providers: [],
bootstrap: [AppComponent]
})

export class AppModule { }

Acabado que permite el enrutamiento mediante la sustitución de todo el HTML en el archivo app.component.html con el etiqueta:


Run ng servir en su terminal, si no lo ha hecho, a continuación, vaya a http: // localhost: 4200 / login. Si todo ha ido bien debería ver el sólo un texto de prueba.

Bootstrap Estilo

para añadir rápidamente un poco de estilo, actualizar el index.html , añadiendo en Bootstrap y envolver la en un recipiente:





Angular4Auth<itle><br /> <base href="/"><br /> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> </head><br /> <body></p> <div class="container"> <app-root></app-root> </div> <p></body><br /> </html><br /> </code> </p> <p> Debería ver el auto aplicación vuelva a cargar tan pronto como guarde. </p> <h2> de autenticación Servicio </h2> <p> A continuación, vamos a crear un servicio global para manejar un usuario que entra, cerrar la sesión, y hasta la firma: </p> <p> <code>$ ng generate service services/auth<br /> </code> </p> <p> Editar la <em> auth.service.ts </em> manera que tiene el siguiente código: </p> <p> <code>import { Injectable } from '@angular/core';</p> <p>@Injectable()<br /> export class AuthService {<br /> test(): string {<br /> return 'working';<br /> }<br /> }<br /> </code> </p> <p> Recuerde cómo los proveedores trabajaron en angular 1? Eran objetos globales que almacena un solo estado. Cuando los datos de un proveedor de cambiar, cualquier objeto que se había inyectado que recibiría proveedor de las actualizaciones. En angular 4, proveedores conservan su comportamiento especial y se definen con el decorador @Injectable. </p> <h3> cordura Compruebe </h3> <p> antes de añadir nada significativo para AuthService, vamos a hacer que el servicio en sí está conectado correctamente. Para ello, dentro <em> login.component.ts </em> inyectar el servicio y llamar al método test (): </p> <p> <code>import { Component, OnInit } from '@angular/core';<br /> import { AuthService } from '../../services/auth.service';</p> <p>@Component({<br /> selector: 'login',<br /> templateUrl: './login.component.html',<br /> styleUrls: ['./login.component.css']<br /> })</p> <p>export class LoginComponent implements OnInit {<br /> test: string = 'just a test';<br /> constructor(private auth: AuthService) {}<br /> ngOnInit(): void {<br /> console.log(this.auth.test());<br /> }<br /> }<br /> </code> </p> <p> Hemos introducido algunos nuevos conceptos y palabras clave. La función del constructor () es un método especial que se utiliza para configurar una nueva instancia de una clase. El constructor () es donde se pasa ningún parámetro que la clase requiere, incluyendo cualquier proveedor (es decir, AuthService) que queremos inyectar. A máquina de escribir, podemos ocultar variables desde el mundo exterior con la palabra clave privada. Pasar una variable privada en el constructor es un atajo para definirlo dentro de la clase y luego asignar el valor del argumento a la misma. Observe cómo la variable de autenticación es accesible al este objeto después de que se pasa al constructor. </p> <p> Nos implementa la interfaz OnInit para asegurar que se define explícitamente una función ngOnInit (). La implementación asegura OnInit que nuestro componente se llama después de la primera comprobación de detección de cambio. Esta función se llama una vez cuando los primeros inicializa componentes, por lo que es el lugar ideal para los datos de configure que se basa en otras clases angular. </p> <p> componentes de diferencia, que se añaden de forma automática, los servicios tienen que ser importados y configurado en el @NgModule manualmente. Así que, para que funcione, usted también tendrá que importar el AuthService en <em> app.module.ts </em> y añadirlo a los proveedores de: </p> <p> <code>import { BrowserModule } from '@angular/platform-browser';<br /> import { NgModule } from '@angular/core';<br /> import { RouterModule } from '@angular/router';</p> <p>import { AppComponent } from './app.component';<br /> import { LoginComponent } from './components/login/login.component';<br /> import { AuthService } from './services/auth.service';</p> <p>@NgModule({<br /> declarations: [<br /> AppComponent,<br /> LoginComponent,<br /> ],<br /> imports: [<br /> BrowserModule,<br /> RouterModule.forRoot([<br /> { path: 'login', component: LoginComponent }<br /> ])<br /> ],<br /> providers: [AuthService],<br /> bootstrap: [AppComponent]<br /> })</p> <p>export class AppModule { }<br /> </code> </p> <p> Ejecutar el servidor y vaya a http: // localhost: 4200 / login . Debería ver trabajar conectado a la consola de JavaScript. </p> <h3> usuario mango de sesión </h3> <p> Para registrar un usuario en, actualizar el AuthService así: </p> <p> <code>import { Injectable } from '@angular/core';<br /> import { Headers, Http } from '@angular/http';<br /> import 'rxjs/add/operatoroPromise';</p> <p>@Injectable()<br /> export class AuthService {<br /> private BASE_URL: string = 'http://localhost:5000/auth';<br /> private headers: Headers = new Headers({'Content-Type': 'application/json'});<br /> constructor(private http: Http) {}<br /> login(user): Promise<any> {<br /> let url: string = `${this.BASE_URL}/login`;<br /> return this.http.post(url, user, {headers: this.headers}).toPromise();<br /> }<br /> }<br /> </code> </p> <p> Empleamos la ayuda de algunas clases incorporadas angular, los encabezados HTTP, y para manejar nuestras llamadas AJAX al servidor. </p> <p> Además, la actualización del <em> app.module.ts </em> archivo para importar el HttpModule. </p> <p> <code>import { BrowserModule } from '@angular/platform-browser';<br /> import { NgModule } from '@angular/core';<br /> import { RouterModule } from '@angular/router';<br /> import { HttpModule } from '@angular/http';</p> <p>import { AppComponent } from './app.component';<br /> import { LoginComponent } from './components/login/login.component';<br /> import { AuthService } from './services/auth.service';</p> <p>@NgModule({<br /> declarations: [<br /> AppComponent,<br /> LoginComponent,<br /> ],<br /> imports: [<br /> BrowserModule,<br /> HttpModule,<br /> RouterModule.forRoot([<br /> { path: 'login', component: LoginComponent }<br /> ])<br /> ],<br /> providers: [AuthService],<br /> bootstrap: [AppComponent]<br /> })</p> <p>export class AppModule { }<br /> </code> </p> <p> En este caso, estamos utilizando el servicio HTTP para enviar una petición AJAX a la / usuario / login punto final. Esto devuelve un objeto de la promesa. </p> <p> <strong> NOTA: </strong>, asegúrese de quitárselas console.log (this.auth.test ()); desde el componente LoginComponent. Ir de </p> <h3> Registro de Usuario </h3> <p> Let adelante y añadir la posibilidad de registrar un usuario, así, que es similar al registro de un usuario en. Actualizar <em> src / app / servicios / auth.service.ts </em>, tomando nota del método de registro : </p> <p> <code>import { Injectable } from '@angular/core';<br /> import { Headers, Http } from '@angular/http';<br /> import 'rxjs/add/operatoroPromise';</p> <p>@Injectable()<br /> export class AuthService {<br /> private BASE_URL: string = 'http://localhost:5000/auth';<br /> private headers: Headers = new Headers({'Content-Type': 'application/json'});<br /> constructor(private http: Http) {}<br /> login(user): Promise<any> {<br /> let url: string = `${this.BASE_URL}/login`;<br /> return this.http.post(url, user, {headers: this.headers}).toPromise();<br /> }<br /> register(user): Promise<any> {<br /> let url: string = `${this.BASE_URL}/register`;<br /> return this.http.post(url, user, {headers: this.headers}).toPromise();<br /> }<br /> }<br /> </code> </p> <p> Ahora, para probar esto tenemos que configurar un extremo trasero … Configuración del lado del servidor </p> <h2> </h2> <p> Por el lado del servidor, vamos a utilizar el proyecto terminado a partir de una entrada en el blog anterior, basada en token de autenticación con Matraz. Usted puede ver el código desde el repositorio matraz de JWT-auth. </p> <p> <strong> NOTA: </strong> no dude en utilizar su propio servidor, sólo asegúrese de actualizar la URL base en el AuthService. </p> <p> Clon la estructura del proyecto en una nueva ventana de terminal: </p> <p> <code>$ git clone https://github.com/realpython/flask-jwt-auth<br /> </code> </p> <p> Siga las instrucciones en el README para configurar el proyecto, asegurándose de que las pruebas pasan antes de continuar. Una vez hecho esto, ejecutar el servidor con la ejecución del servidor python manage.py, que se escucha en el puerto 5000. </p> <h2> cordura test Check </h2> <p>, a actualizar LoginComponent utilizar el inicio de sesión y registrar los métodos del servicio: </p> <p> <code>import { Component, OnInit } from '@angular/core';<br /> import { AuthService } from '../../services/auth.service';</p> <p>@Component({<br /> selector: 'login',<br /> templateUrl: './login.component.html',<br /> styleUrls: ['./login.component.css']<br /> })<br /> export class LoginComponent implements OnInit {<br /> test: string = 'just a test';<br /> constructor(private auth: AuthService) {}<br /> ngOnInit(): void {<br /> let sampleUser: any = {<br /> email: 'michael@realpython.com' as string,<br /> password: 'michael' as string<br /> };<br /> this.auth.register(sampleUser)<br /> .then((user) => {<br /> console.log(user.json());<br /> })<br /> .catch((err) => {<br /> console.log(err);<br /> });<br /> this.auth.login(sampleUser).then((user) => {<br /> console.log(user.json());<br /> })<br /> .catch((err) => {<br /> console.log(err);<br /> });<br /> }<br /> }<br /> </code> </p> <p> Actualizar http: // localhost: 4200 / inicio de sesión en el navegador y debería ver un éxito en la consola JavaScript, después de que el usuario está conectado, con el token: </p> <p> <code>{<br /> "auth_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1M…jozfQ.bPNQb3C98yyNe0LDyl1Bfkp0Btn15QyMxZnBoE9RQMI",<br /> "message": "Successfully logged in.",<br /> "status": "success"<br /> }<br /> </code> </p> <h2> de autenticación de sesión </h2> <p> actualización <em> login.component.html </em>: tomar </p> <p> <code></p> <div class="row"> <div class="col-md-4"> <h1>Login</h1> <hr> <p></p> <form (ngSubmit)="onLogin()" novalidate> <div class="form-group"> <label for="email">Email</label><br /> <input type="text" class="form-control" id="email" placeholder="enter email" [(ngModel)]="user.email" name="email" required> </div> <div class="form-group"> <label for="password">Password</label><br /> <input type="password" class="form-control" id="password" placeholder="enter password" [(ngModel)]="user.password" name="password" required> </div> <p> <button type="submit" class="btn btn-default">Submit</button><br /> </form> </p></div> </div> <p></code> </p> <p> nota de la forma. Se utilizó el [(ngModel)] directiva sobre cada una de las entradas de formulario para capturar esos valores en el controlador. Además, cuando se envía el formulario, la directiva ngSubmit controla el evento al disparar el método onLogin (). </p> <p> Ahora, vamos a actualizar el código del componente, añadiendo en onLogin (): </p> <p> <code>import { Component } from '@angular/core';<br /> import { AuthService } from '../../services/auth.service';<br /> import { User } from '../../models/user';</p> <p>@Component({<br /> selector: 'login',<br /> templateUrl: './login.component.html',<br /> styleUrls: ['./login.component.css']<br /> })<br /> export class LoginComponent {<br /> user: User = new User();<br /> constructor(private auth: AuthService) {}<br /> onLogin(): void {<br /> this.auth.login(this.user)<br /> .then((user) => {<br /> console.log(user.json());<br /> })<br /> .catch((err) => {<br /> console.log(err);<br /> });<br /> }<br /> }<br /> </code> </p> <p> Si tiene el servidor web angular corriendo, debería ver el error No se puede encontrar el módulo ‘../../models/user’ en el navegador . Antes de nuestro código funcionará, necesitamos crear un modelo de usuario. </p> <p> <code>$ ng generate class models/user<br /> </code> </p> <p> actualización <em> src / app / models / user.ts </em>: </p> <p> <code>export class User {<br /> constructor(email?: string, password?: string) {}<br /> }<br /> </code> </p> <p> Nuestro modelo de usuario tiene dos propiedades, correo electrónico y contraseña. Los ? personaje es un operador especial que indica que la inicialización del usuario con los valores de correo electrónico y contraseña explícitos es opcional. Esto es equivalente a la clase siguiente en Python: </p> <p> <code>class User(object):<br /> def __init__(self, email=None, password=None):<br /> self.email = email<br /> self.password = password<br /> </code> </p> <p> no se olvide de actualizar <em> auth.service.ts </em> utilizar el nuevo objeto. </p> <p> <code>import { Injectable } from '@angular/core';<br /> import { Headers, Http } from '@angular/http';<br /> import { User } from '../models/user';<br /> import 'rxjs/add/operatoroPromise';</p> <p>@Injectable()<br /> export class AuthService {<br /> private BASE_URL: string = 'http://localhost:5000/auth';<br /> private headers: Headers = new Headers({'Content-Type': 'application/json'});<br /> constructor(private http: Http) {}<br /> login(user: User): Promise<any> {<br /> let url: string = `${this.BASE_URL}/login`;<br /> return this.http.post(url, user, {headers: this.headers}).toPromise();<br /> }<br /> register(user: User): Promise<any> {<br /> let url: string = `${this.BASE_URL}/register`;<br /> return this.http.post(url, user, {headers: this.headers}).toPromise();<br /> }<br /> }<br /> </code> </p> <p> Una última cosa. Tenemos que importar el FormsModule en el <em> app.module.ts </em> archivo. </p> <p> <code>import { BrowserModule } from '@angular/platform-browser';<br /> import { NgModule } from '@angular/core';<br /> import { RouterModule } from '@angular/router';<br /> import { HttpModule } from '@angular/http';<br /> import { FormsModule } from '@angular/forms';</p> <p>import { AppComponent } from './app.component';<br /> import { LoginComponent } from './components/login/login.component';<br /> import { AuthService } from './services/auth.service';</p> <p>@NgModule({<br /> declarations: [<br /> AppComponent,<br /> LoginComponent,<br /> ],<br /> imports: [<br /> BrowserModule,<br /> HttpModule,<br /> FormsModule,<br /> RouterModule.forRoot([<br /> { path: 'login', component: LoginComponent }<br /> ])<br /> ],<br /> providers: [AuthService],<br /> bootstrap: [AppComponent]<br /> })</p> <p>export class AppModule { }<br /> </code> </p> <p> lo tanto, cuando se envía el formulario, que captura el correo electrónico y la contraseña y pasar al método de inicio de sesión () en el servicio. Prueba </p> <p> esto con- correo electrónico </p> <ul> <li>: michael@realpython.com </li> <li> contraseña: Michael </li> </ul> <p> Una vez más, debería ver un éxito en la consola JavaScript en la ficha. </p> <h2> de autenticación Registro </h2> <p> Al igual que para la funcionalidad de inicio de sesión, tenemos que añadir un componente para el registro de un usuario. Para empezar, la generación de un nuevo componente de Registro: </p> <p> <code>$ ng generate component components/register<br /> </code> </p> <p> actualización <em> src / app / componentes / registrarse / register.component.html </em>: </p> <p> <code></p> <div class="row"> <div class="col-md-4"> <h1>Register</h1> <hr> <p></p> <form (ngSubmit)="onRegister()" novalidate> <div class="form-group"> <label for="email">Email</label><br /> <input type="text" class="form-control" id="email" placeholder="enter email" [(ngModel)]="user.email" name="email" required> </div> <div class="form-group"> <label for="password">Password</label><br /> <input type="password" class="form-control" id="password" placeholder="enter password" [(ngModel)]="user.password" name="password" required> </div> <p> <button type="submit" class="btn btn-default">Submit</button><br /> </form> </p></div> </div> <p></code> </p> <p> A continuación, actualice <em> src / app / componentes / registrarse / register.component.ts </em> como sigue: </p> <p> <code>import { Component } from '@angular/core';<br /> import { AuthService } from '../../services/auth.service';<br /> import { User } from '../../models/user';</p> <p>@Component({<br /> selector: 'register',<br /> templateUrl: './register.component.html',<br /> styleUrls: ['./register.component.css']<br /> })<br /> export class RegisterComponent {<br /> user: User = new User();<br /> constructor(private auth: AuthService) {}<br /> onRegister(): void {<br /> this.auth.register(this.user)<br /> .then((user) => {<br /> console.log(user.json());<br /> })<br /> .catch((err) => {<br /> console.log(err);<br /> });<br /> }<br /> }<br /> </code> </p> <p> Añadir un nuevo controlador de ruta a la <em> app.module.ts archivo </em>: </p> <p> <code>RouterModule.forRoot([<br /> { path: 'login', component: LoginComponent },<br /> { path: 'register', component: RegisterComponent }<br /> ])<br /> </code> </p> <p> probarlo mediante el registro de un nuevo usuario! </p> <h2> Almacenamiento local </h2> <p> A continuación, vamos a añadir el token de almacenamiento local para la persistencia mediante la sustitución de la console.log (user.json ()); con localStorage.setItem ( ‘contador’, user.data.token); <em> en src / app / componentes / login / login.component.ts </em>: </p> <p> <code>onLogin(): void {<br /> this.auth.login(this.user)<br /> .then((user) => {<br /> localStorage.setItem('token', user.json().auth_token);<br /> })<br /> .catch((err) => {<br /> console.log(err);<br /> });<br /> }<br /> </code> </p> <p> hacer lo mismo dentro de <em> src / app / componentes / Registro / register.component.ts </em>: </p> <p> <code>onRegister(): void {<br /> this.auth.register(this.user)<br /> .then((user) => {<br /> localStorage.setItem('token', user.json().auth_token);<br /> })<br /> .catch((err) => {<br /> console.log(err);<br /> });<br /> }<br /> </code> </p> <p> Mientras esa señal está presente , el usuario puede considerarse iniciado sesión. Y, cuando un usuario necesita para hacer una petición AJAX, esa señal puede ser utilizada. </p> <p> <strong> NOTA: </strong> Además de la razón, también se puede añadir el identificador de usuario y correo electrónico para almacenamiento local. Sólo se necesita actualizar el servidor para enviar de vuelta esa información cuando un usuario se conecta. </p> <p> prueba </p> <p> esto. Asegúrese de que el elemento está presente en el almacenamiento local después de iniciar sesión. </p> <h2> Condición de Usuario </h2> <p> para poner a prueba la persistencia de inicio de sesión, podemos añadir una nueva vista que verifica que el usuario está conectado y que el token es válido. </p> <p> Añadir el siguiente método para AuthService: </p> <p> <code>ensureAuthenticated(token): Promise<any> {<br /> let url: string = `${this.BASE_URL}/status`;<br /> let headers: Headers = new Headers({<br /> 'Content-Type': 'application/json',<br /> Authorization: `Bearer ${token}`<br /> });<br /> return this.http.get(url, {headers: headers}).toPromise();<br /> }<br /> </code> </p> <p> Tomar nota de autorización: ‘portador’ + token. Esto se llama un esquema portador, que se envía junto con la solicitud. En el servidor, simplemente estamos comprobando la cabecera de Autorización, y luego si el token es válido. ¿Puede encontrar este código en el lado del servidor? </p> <p> A continuación, generar un nuevo componente de estado: </p> <p> <code>$ ng generate component components/status<br /> </code> </p> <p> Crear la plantilla HTML, <em> src / app / componentes / estado / status.component.html </em>: </p> <p> <code></p> <div class="row"> <div class="col-md-4"> <h1>User Status</h1> <hr> <p></p> <p>Logged In? {{isLoggedIn}}</p> </p></div> </div> <p></code> </p> <p> Y cambiar el código del componente en <em> src / app / componentes / estado / status.component.ts </em>: </p> <p> <code>import { Component, OnInit } from '@angular/core';<br /> import { AuthService } from '../../services/auth.service';</p> <p>@Component({<br /> selector: 'status',<br /> templateUrl: './status.component.html',<br /> styleUrls: ['./status.component.css']<br /> })<br /> export class StatusComponent implements OnInit {<br /> isLoggedIn: boolean = false;<br /> constructor(private auth: AuthService) {}<br /> ngOnInit(): void {<br /> const token = localStorage.getItem('token');<br /> if (token) {<br /> this.auth.ensureAuthenticated(token)<br /> .then((user) => {<br /> console.log(user.json());<br /> if (user.json().status === 'success') {<br /> this.isLoggedIn = true;<br /> }<br /> })<br /> .catch((err) => {<br /> console.log(err);<br /> });<br /> }<br /> }<br /> }<br /> </code> </p> <p> Por último, añadir un nuevo controlador de ruta a la <em> app.module.ts </em> archivo: </p> <p> <code>RouterModule.forRoot([<br /> { path: 'login', component: LoginComponent },<br /> { path: 'register', component: RegisterComponent },<br /> { path: 'status', component: StatusComponent }<br /> ])<br /> </code> </p> <p> listo para la prueba? Entrar y vaya a http: // localhost: 4200 / estado. Si hay una ficha en el almacenamiento local, debería ver: </p> <p> <code>{<br /> "message": "Signature expired. Please log in again.",<br /> "status": "fail"<br /> }<br /> </code> </p> <p> ¿Por qué? Bueno, cuando uno profundiza en el lado del servidor, se encuentra que el testigo sólo es válida durante 5 segundos en <em> proyecto / servidor / models.py </em>: </p> <p> <code>def encode_auth_token(self, user_id):<br /> """<br /> Generates the Auth Token<br /> :return: string<br /> """<br /> try:<br /> payload = {<br /> 'exp': datetime.datetime.utcnow() + datetime.timedelta(days=0, seconds=5),<br /> 'iat': datetime.datetime.utcnow(),<br /> 'sub': user_id<br /> }<br /> return jwt.encode(<br /> payload,<br /> app.config.get('SECRET_KEY'),<br /> algorithm='HS256'<br /> )<br /> except Exception as e:<br /> return e<br /> </code> </p> <p> actualización de este a 1 día: </p> <p> <code>'exp': datetime.datetime.utcnow() + datetime.timedelta(days=1, seconds=0)<br /> </code> </p> <p> Y entonces prueba de nuevo. Ahora debería ver algo como:. </p> <p> <code>{<br /> "data": {<br /> "admin": false,<br /> "email": "michael@realpython.com",<br /> "registered_on": "Sun, 13 Aug 2017 17:21:52 GMT",<br /> "user_id": 4<br /> },<br /> "status": "success"<br /> }<br /> </code> </p> <p> Por último, vamos a redirigir a la página de estado después de un usuario se registra o los registros de actualización con éxito en <em> src / app / componentes / login / login.component.ts </em> así: </p> <p> <code>import { Component } from '@angular/core';<br /> import { Router } from '@angular/router';<br /> import { AuthService } from '../../services/auth.service';<br /> import { User } from '../../models/user';</p> <p>@Component({<br /> selector: 'login',<br /> templateUrl: './login.component.html',<br /> styleUrls: ['./login.component.css']<br /> })<br /> export class LoginComponent {<br /> user: User = new User();<br /> constructor(private router: Router, private auth: AuthService) {}<br /> onLogin(): void {<br /> this.auth.login(this.user)<br /> .then((user) => {<br /> localStorage.setItem('token', user.json().auth_token);<br /> this.router.navigateByUrl('/status');<br /> })<br /> .catch((err) => {<br /> console.log(err);<br /> });<br /> }<br /> }<br /> </code> </p> <p> Entonces actualización <em> src / app / componentes / registrarse / register.component.ts </em>: </p> <p> <code>import { Component } from '@angular/core';<br /> import { Router } from '@angular/router';<br /> import { AuthService } from '../../services/auth.service';<br /> import { User } from '../../models/user';</p> <p>@Component({<br /> selector: 'register',<br /> templateUrl: './register.component.html',<br /> styleUrls: ['./register.component.css']<br /> })<br /> export class RegisterComponent {<br /> user: User = new User();<br /> constructor(private router: Router, private auth: AuthService) {}<br /> onRegister(): void {<br /> this.auth.register(this.user)<br /> .then((user) => {<br /> localStorage.setItem('token', user.json().auth_token);<br /> this.router.navigateByUrl('/status');<br /> })<br /> .catch((err) => {<br /> console.log(err);<br /> });<br /> }<br /> }<br /> </code> </p> <p> probarlo! </p> <h2> Ruta Restricción </h2> <p> En este momento, son todas las rutas abiertas; Por lo tanto, independientemente de si un usuario está conectado o no, que pueden acceder a cada ruta. Ciertas rutas deben restringirse si un usuario no ha iniciado sesión, mientras que otras rutas deben restringirse si un usuario se registra en: </p> <p> Para lograr esto, añadir ya sea EnsureAuthenticated o LoginRedirect a cada ruta, dependiendo de si se desea para guiar al usuario a la vista de estado o en la vista de inicio de sesión. </p> <p> de inicio mediante la creación de dos nuevos servicios: </p> <p> <code>$ ng generate service services/ensure-authenticated<br /> $ ng generate service services/login-redirect<br /> </code> </p> <p> reemplace el código en los <em> garantizar-authenticated.service.ts archivos </em> de la siguiente manera: </p> <p> <code>import { Injectable } from '@angular/core';<br /> import { CanActivate, Router } from '@angular/router';<br /> import { AuthService } from './auth.service';</p> <p>@Injectable()<br /> export class EnsureAuthenticated implements CanActivate {<br /> constructor(private auth: AuthService, private router: Router) {}<br /> canActivate(): boolean {<br /> if (localStorage.getItem('token')) {<br /> return true;<br /> }<br /> else {<br /> this.router.navigateByUrl('/login');<br /> return false;<br /> }<br /> }<br /> }<br /> </code> </p> <p> y reemplazar el código de inicio de sesión en el <em>-redirect.service.ts </em> como tal : </p> <p> <code>import { Injectable } from '@angular/core';<br /> import { CanActivate, Router } from '@angular/router';<br /> import { AuthService } from './auth.service';</p> <p>@Injectable()<br /> export class LoginRedirect implements CanActivate {<br /> constructor(private auth: AuthService, private router: Router) {}<br /> canActivate(): boolean {<br /> if (localStorage.getItem('token')) {<br /> this.router.navigateByUrl('/status');<br /> return false;<br /> }<br /> else {<br /> return true;<br /> }<br /> }<br /> }<br /> </code> </p> <p> Por último, la actualización del archivo de <em> app.module.ts </em> importar y configurar los nuevos servicios: </p> <p> <code>import { BrowserModule } from '@angular/platform-browser';<br /> import { NgModule } from '@angular/core';<br /> import { RouterModule } from '@angular/router';<br /> import { HttpModule } from '@angular/http';<br /> import { FormsModule } from '@angular/forms';</p> <p>import { AppComponent } from './app.component';<br /> import { LoginComponent } from './components/login/login.component';<br /> import { AuthService } from './services/auth.service';<br /> import { RegisterComponent } from './components/register/register.component';<br /> import { StatusComponent } from './components/status/status.component';<br /> import { EnsureAuthenticated } from './services/ensure-authenticated.service';<br /> import { LoginRedirect } from './services/login-redirect.service';</p> <p>@NgModule({<br /> declarations: [<br /> AppComponent,<br /> LoginComponent,<br /> RegisterComponent,<br /> StatusComponent,<br /> ],<br /> imports: [<br /> BrowserModule,<br /> HttpModule,<br /> FormsModule,<br /> RouterModule.forRoot([<br /> {<br /> path: 'login',<br /> component: LoginComponent,<br /> canActivate: [LoginRedirect]<br /> },<br /> {<br /> path: 'register',<br /> component: RegisterComponent,<br /> canActivate: [LoginRedirect]<br /> },<br /> {<br /> path: 'status',<br /> component: StatusComponent,<br /> canActivate:<br /> [EnsureAuthenticated]<br /> }<br /> ])<br /> ],<br /> providers: [<br /> AuthService,<br /> EnsureAuthenticated,<br /> LoginRedirect<br /> ],<br /> bootstrap: [AppComponent]<br /> })</p> <p>export class AppModule { }<br /> </code> </p> <p> Nota cómo estamos añadiendo nuestros servicios a una propiedad nueva ruta, canActivate. El sistema de enrutamiento utiliza los servicios de la matriz canActivate para determinar si se muestra la ruta URL solicitada. Si la ruta tiene LoginRedirect y el usuario ya está conectado, entonces van a ser redirigido a la vista de estado. Incluyendo el servicio EnsureAuthenticated redirige al usuario a la vista de inicio de sesión si intentan acceder a una URL que requiere autenticación. Prueba </p> <p> por última vez. de </p> <h2> ¿Qué sigue? </h2> <p> En este tutorial, que pasó por el proceso de autenticación de la adición de un angular 4 + Frasco aplicación usando JSON Web Tokens. </p> <p> ¿Qué sigue? </p> <p> Trate de cambiar a cabo el back-end Frasco por un marco Web diferente, como Django o botella, utilizando los siguientes criterios de valoración: </p> <ul> <li> / auth / registrarse </li> <li> / auth / login </li> <li> / auth / cierre de sesión </li> <li> / auth / </li> <p> usuario </ul> <p> Si desea ver cómo construir una aplicación web completa Python usando Frasco, echa un vistazo a esta serie de videos: </p> <p> Bono <strong> gratuito: </strong> Haga clic aquí para obtener acceso a un video Frasco + Guía de aprendizaje gratuito que muestra cómo construir aplicación web Frasco, paso a paso. </p> <p> Añadir a las preguntas y / o comentarios a continuación. Coge el código final de la cesión temporal angular4-auth. </p> </div><!-- .entry-content --> </div><!-- .post-inner --> <div class="section-inner"> </div><!-- .section-inner --> <nav class="pagination-single section-inner" aria-label="Entrada" role="navigation"> <hr class="styled-separator is-style-wide" aria-hidden="true" /> <div class="pagination-single-inner"> <a class="previous-post" href="https://eltecnofilo.es/cartilla-en-python-decoradores/"> <span class="arrow" aria-hidden="true">←</span> <span class="title"><span class="title-inner">Cartilla en Python decoradores</span></span> </a> <a class="next-post" href="https://eltecnofilo.es/python-api-rest-con-el-frasco-connexion-y-sqlalchemy-parte-4/"> <span class="arrow" aria-hidden="true">→</span> <span class="title"><span class="title-inner">Python API REST con el frasco, Connexion, y SQLAlchemy – Parte 4</span></span> </a> </div><!-- .pagination-single-inner --> <hr class="styled-separator is-style-wide" aria-hidden="true" /> </nav><!-- .pagination-single --> <div class="comments-wrapper section-inner"> <div id="respond" class="comment-respond"> <h2 id="reply-title" class="comment-reply-title">Deja un comentario <small><a rel="nofollow" id="cancel-comment-reply-link" href="/modulo-pathlib-de-python-3-la-doma-del-sistema-de-archivos/#respond" style="display:none;">Cancelar la respuesta</a></small></h2><form action="https://eltecnofilo.es/wp-comments-post.php" method="post" id="commentform" class="section-inner thin max-percentage" novalidate><p class="comment-notes"><span id="email-notes">Tu dirección de correo electrónico no será publicada.</span> Los campos obligatorios están marcados con <span class="required">*</span></p><p class="comment-form-comment"><label for="comment">Comentario</label> <textarea id="comment" name="comment" cols="45" rows="8" maxlength="65525" required="required"></textarea></p><p class="comment-form-author"><label for="author">Nombre <span class="required">*</span></label> <input id="author" name="author" type="text" value="" size="30" maxlength="245" required='required' /></p> <p class="comment-form-email"><label for="email">Correo electrónico <span class="required">*</span></label> <input id="email" name="email" type="email" value="" size="30" maxlength="100" aria-describedby="email-notes" required='required' /></p> <p class="comment-form-url"><label for="url">Web</label> <input id="url" name="url" type="url" value="" size="30" maxlength="200" /></p> <p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes" /> <label for="wp-comment-cookies-consent">Guardar mi nombre, correo electrónico y sitio web en este navegador para la próxima vez que haga un comentario.</label></p> <p class="form-submit"><input name="submit" type="submit" id="submit" class="submit" value="Publicar el comentario" /> <input type='hidden' name='comment_post_ID' value='6669' id='comment_post_ID' /> <input type='hidden' name='comment_parent' id='comment_parent' value='0' /> </p></form> </div><!-- #respond --> </div><!-- .comments-wrapper --> </article><!-- .post --> </main><!-- #site-content --> <div class="footer-nav-widgets-wrapper header-footer-group"> <div class="footer-inner section-inner"> <aside class="footer-widgets-outer-wrapper" role="complementary"> <div class="footer-widgets-wrapper"> <div class="footer-widgets column-one grid-item"> <div class="widget widget_search"><div class="widget-content"><form role="search" method="get" class="search-form" action="https://eltecnofilo.es/"> <label for="search-form-2"> <span class="screen-reader-text">Buscar:</span> <input type="search" id="search-form-2" class="search-field" placeholder="Buscar …" value="" name="s" /> </label> <input type="submit" class="search-submit" value="Buscar" /> </form> </div></div> <div class="widget widget_recent_entries"><div class="widget-content"> <h2 class="widget-title subheading heading-size-3">Entradas recientes</h2> <ul> <li> <a href="https://eltecnofilo.es/vps-cloud-hosting/">VPS cloud hosting</a> </li> <li> <a href="https://eltecnofilo.es/versiones-de-ejecucion-de-python-en-acoplable-como-probar-la-ultima-release-python/">Versiones de ejecución de Python en acoplable: Cómo probar la última Release Python</a> </li> <li> <a href="https://eltecnofilo.es/leer-y-escribir-archivos-csv/">Leer y escribir archivos CSV</a> </li> <li> <a href="https://eltecnofilo.es/python-puro-vs-vs-numpy-tensorflow-comparacion-de-rendimiento/">Python puro vs vs NumPy TensorFlow Comparación de Rendimiento</a> </li> <li> <a href="https://eltecnofilo.es/estructura-python-programa-lexico/">Estructura Python Programa léxico</a> </li> </ul> </div></div><div class="widget widget_recent_comments"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Comentarios recientes</h2><ul id="recentcomments"><li class="recentcomments"><span class="comment-author-link"><a href="https://wordpress.org/" rel="external nofollow ugc" class="url">A WordPress Commenter</a></span> en <a href="https://eltecnofilo.es/hello-world/#comment-1">Hello world!</a></li></ul></div></div> </div> <div class="footer-widgets column-two grid-item"> <div class="widget widget_archive"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Archivos</h2> <ul> <li><a href='https://eltecnofilo.es/2020/04/'>abril 2020</a></li> <li><a href='https://eltecnofilo.es/2020/03/'>marzo 2020</a></li> <li><a href='https://eltecnofilo.es/2019/12/'>diciembre 2019</a></li> </ul> </div></div><div class="widget widget_categories"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Categorías</h2> <ul> <li class="cat-item cat-item-22"><a href="https://eltecnofilo.es/category/python/">Python</a> </li> <li class="cat-item cat-item-1"><a href="https://eltecnofilo.es/category/uncategorized/">Uncategorized</a> </li> </ul> </div></div><div class="widget widget_meta"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Meta</h2> <ul> <li><a rel="nofollow" href="https://eltecnofilo.es/wp-login.php">Acceder</a></li> <li><a href="https://eltecnofilo.es/feed/">Feed de entradas</a></li> <li><a href="https://eltecnofilo.es/comments/feed/">Feed de comentarios</a></li> <li><a href="https://es.wordpress.org/">WordPress.org</a></li> </ul> </div></div> </div> </div><!-- .footer-widgets-wrapper --> </aside><!-- .footer-widgets-outer-wrapper --> </div><!-- .footer-inner --> </div><!-- .footer-nav-widgets-wrapper --> <footer id="site-footer" role="contentinfo" class="header-footer-group"> <div class="section-inner"> <div class="footer-credits"> <p class="footer-copyright">© 2020 <a href="https://eltecnofilo.es/">My Blog</a> </p><!-- .footer-copyright --> <p class="powered-by-wordpress"> <a href="https://es.wordpress.org/"> Funciona gracias a WordPress </a> </p><!-- .powered-by-wordpress --> </div><!-- .footer-credits --> <a class="to-the-top" href="#site-header"> <span class="to-the-top-long"> Ir arriba <span class="arrow" aria-hidden="true">↑</span> </span><!-- .to-the-top-long --> <span class="to-the-top-short"> Subir <span class="arrow" aria-hidden="true">↑</span> </span><!-- .to-the-top-short --> </a><!-- .to-the-top --> </div><!-- .section-inner --> </footer><!-- #site-footer --> <script src='https://eltecnofilo.es/wp-includes/js/comment-reply.min.js?ver=5.3.3'></script> <script src='https://eltecnofilo.es/wp-includes/js/wp-embed.min.js?ver=5.3.3'></script> <script> /(trident|msie)/i.test(navigator.userAgent)&&document.getElementById&&window.addEventListener&&window.addEventListener("hashchange",function(){var t,e=location.hash.substring(1);/^[A-z0-9_-]+$/.test(e)&&(t=document.getElementById(e))&&(/^(?:a|select|input|button|textarea)$/i.test(t.tagName)||(t.tabIndex=-1),t.focus())},!1); </script> </body> </html>