Readdy Write  
0,00 €
Your View Money
Views: Count
Self 20% 0
Your Content 60% 0

Users by Links 0
u1*(Content+Views) 10% 0
Follow-Follower 0
s2*(Income) 5% 0

Count
Followers 0
Login Register as User

Add Token to webrequests and read User at API

15.02.2023 (👁960)

Add Token to webrequests

 

Wenn man mit Authorisierung in webanwendungen arbeitet, muss man einen Token in den Header einer Web-Anfrage einfĂźgen.

Dieser enthält die verschlßsselten Informationen zum aktuellen User und ist somit eine Zugriffskontrolle.

In Angular wird der Vorgang mit einem Intercept durchgefĂźhrt.

Services/authentication.service.ts

import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http";

import { Injectable } from "@angular/core";

import { Observable } from "rxjs";

import { CookieService } from 'ngx-cookie-service'  //*for using cookies

 

@Injectable()

export class AuthenticationInterceptor implements HttpInterceptor {

    //</ init >

    constructor(private cookieService: CookieService) { }

    //</ init >

 

    //* on any authorize-error 401, add the token to the header

    intercept(

        request: HttpRequest<any>,

        next: HttpHandler,

        //err:HttpErrorResponse                

    ): Observable<HttpEvent<any>> {

        //better check for URL to api-data urls

        const url: string = request.url.toLocaleLowerCase();

        if (url.indexOf("/api/") > 0) {

            //----< if request to api data-backend >----

            var token = this.cookieService.get("t");

            if (token) {

                request = request.clone({

                    //add the jwt token to the header

                    setHeaders: { Authorization: `Bearer ${token}` },   //*token contains userid internal,encrypted

                });

            }

            //----</ if request to api data-backend >----

        }

 

        return next.handle(request);

    }

}

 

 

Add to each outgoing data request the access token into the header.

Therefore only check, if the webrequest goes to /api/

Ein Bild, das Text enthält.

Automatisch generierte Beschreibung

 

 

 

Zusätzlich zum verarbeiten der Authentifizierungen kann die authentication.service.ts verwendet werden

Services/authentication.ts

import { HttpClient, HttpHeaders } from '@angular/common/http';

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

import { BehaviorSubject, map, Observable } from 'rxjs';

import { environment } from 'src/environments/environment';

import { User_Model } from '../models/usermodel';

import { CookieService } from 'ngx-cookie-service'  //*for using cookies

import { Router } from '@angular/router';

 

const url_Api_Auth = environment.apiUrl + "/Authentication";

const httpOptions = {  headers: new HttpHeaders({ 'Content-Type': 'application/json' })};

 

@Injectable({

  providedIn: 'root'

})

export class AuthenticationService implements OnInit{

  //--------< AuthenticationService >--------

  //*opens webapi and gets data

  private userSubject: BehaviorSubject<User_Model  | null>;

  public user: Observable<User_Model | null>;

  public token:string="";

  constructor(private http: HttpClient, private cookieService: CookieService, private router:Router) {

    this.userSubject = new BehaviorSubject(JSON.parse(localStorage.getItem('u')!));

      this.user = this.userSubject.asObservable();      

  }  //*inject web-api caller

 

  ngOnInit() {

    //this.email = localStorage.getItem('e')!;

    this.token = this.cookieService.get("t")!;

  }

 

  //try to register and send result true/false

  //test: public async register(username:string, email:string, password:string):Promise<boolean> {

    public register(username:string, email:string, password:string) {

      //--------< register() >--------

      //*try to /register with email password and get token as result.

      return this.http.post<any>(url_Api_Auth + "/register",{Username:username,Email:email,Password:password})

      .subscribe(

        {

          next: (response_username_token:any ) => {

            //*store token in local storage

            var token=response_username_token.token;

            var username=response_username_token.username;

 

            this.cookieService.set('t', token,365);

            this.token=token;        

            localStorage.setItem('u',JSON.stringify(username))

            this.userSubject.next(username);

            console.log("register ok");

            this.router.navigate(['/home']);

           

            return true;  //->total result is true for the wrapping function

          }

          ,error: (e) => {

            console.log("/register.error:" + e.message);

            alert(e.message);

            return false;   //->total result is true for the wrapping function

          }

          ,complete: () => console.log('register complete')

        });

      //--------</ register() >--------

  }

 

     

//try to register and send result true/false

public async login(email:string, password:string):Promise<boolean> {

  //*try to /register with email password and get token as result.

  //if token is ok, then true else false

  const webrequest=await this.http.post<any>(url_Api_Auth + "/login",{email,password});

  webrequest.subscribe(

    {

      next: (token: string) => {

        //*store token in local storage

        this.cookieService.set("t", token,365);

        this.token=token;

        console.log("login ok");

        this.router.navigate(['/home']);

        return true;

      }

      ,error: (e) => {

        console.log("/login.error:"+ e.message);

        alert(e.message);

        return false;

      }

      ,complete: () => console.log('register complete')

    });

 

  if (this.token!="") return true; else return false;    

}

 

public logout(){

  localStorage.clear();

  this.cookieService.deleteAll();

  this.token="";    

  this.user.pipe(map(u=>{ u!.username="x";}))

}

 

  public getMe(): Observable<string> {

    return this.http.get(

      url_Api_Auth + "/getme", { responseType: 'text' }

    )

  }

}

 

Zuletzt muss der Interceptor in der app.module.ts eingefĂźgt werden

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

import { BrowserModule } from '@angular/platform-browser';

import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';  //*for url to web-api

import { AppRoutingModule } from './app-routing.module';

import { CookieService } from 'ngx-cookie-service';

 

import { AppComponent } from './app.component';

import { ListArticlesComponent } from './components/articles/list-articles/list-articles.component';

import { EditArticleComponent } from './components/articles/edit-article/edit-article.component';

import { ReadArticleComponent } from './components/articles/read-article/read-article.component';

import { FormsModule } from '@angular/forms';

import { UserComponent } from './components/user/user.component';

import { AuthenticationInterceptor } from './services/authentication.interceptor';

import { RegisterComponent } from './components/user/register/register.component';

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

 

@NgModule({

  //*Insert Components in Declatation

  declarations: [

    AppComponent, //*main page

    ListArticlesComponent,

    EditArticleComponent,

    ReadArticleComponent,

    UserComponent,

    RegisterComponent,

    LoginComponent,

  ],

  //*Insert Modules in Import

  imports: [

    BrowserModule,

    AppRoutingModule, //*imports app-routing file

    HttpClientModule,  //for web-api cll

    FormsModule

  ],

 

  //*authenticate intercepter

  providers: [{

    provide: HTTP_INTERCEPTORS,

    useClass:AuthenticationInterceptor,

    multi:true

  },

  {    provide: CookieService      }

  ],

  bootstrap: [AppComponent]

})

export class AppModule { }

 

 

 

 

 

BACKEND

In der Web-API kann der User dann ausgelesen werden:

Asp.net Core API Backend
ArticlesController.cs

// GET: api/<ArticlesController>

        [HttpGet("get_list")]

        public async Task<ActionResult<List<ArticleDbModel>>>Get_List()

        {

            var userGUID = HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);

           

            //load top 10

            //var query = from t in _dbContext.tbl_Articles orderby t.IDArticle descending select t;

            var query = from t in _dbContext.tbl_Articles orderby t.IDArticle descending select new {

                idarticle=t.IDArticle,

                title =t.Title

            };

            var list_Articles=query.Take(10);

            var output_list = await list_Articles.ToListAsync();

            //return list_Artcles.ToList();

            return Ok(output_list);  //👍 better loading

        }

Hierzu muss die Authorisierung mit Java JWT tokens in der App eingefĂźgt werden

using Microsoft.AspNetCore.Authentication.JwtBearer;

using Microsoft.EntityFrameworkCore;

using Microsoft.IdentityModel.Tokens;

using Microsoft.OpenApi.Models;

using Swashbuckle.AspNetCore.Filters;

using System.Text;

using Services;

using webapp_codedocu.Data;

 

 

#region //==< Builder.Configure >==

//==< Builder >==

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

 

    //< get_config >

    string config_App_SignInKey = builder.Configuration.GetSection("AppSettings").GetValue<String>("App_SignInKey")

        ?? throw new InvalidOperationException("AppSignInKey missing in Config.AppSettings");

 

    string url_FrontEnd = builder.Configuration.GetSection("AppSettings").GetValue<String>("Url_FrontEnd")

        ?? throw new InvalidOperationException("UrlFrontEnd is missing in Config.AppSettings");

 

    string connectionString = builder.Configuration.GetConnectionString("DefaultConnection")

        ?? throw new InvalidOperationException("Connection string not found in Config");

 

    //</ get_config >

 

    //* Connect Database

    builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString));

 

    builder.Services.AddControllers();

    // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle

    builder.Services.AddEndpointsApiExplorer();

 

    builder.Services.AddScoped<IUserService, UserService>();

    builder.Services.AddHttpContextAccessor();

 

 

 

    //builder.Services.AddSwaggerGen();

    builder.Services.AddSwaggerGen(options =>

    {

        options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme

        {

            Description = "Standard Authorization header using the Bearer scheme (\"bearer {token}\")",

            In = ParameterLocation.Header,

            Name = "Authorization",

            Type = SecuritySchemeType.ApiKey

        });

 

        options.OperationFilter<SecurityRequirementsOperationFilter>();         //by Swashbuckle

    });

    builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)  //by Microsoft.AspCore.Authentication

        .AddJwtBearer(options =>

        {

            options.TokenValidationParameters = new TokenValidationParameters

            {

                ValidateIssuerSigningKey = true,

                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config_App_SignInKey)), //*Decode AccessToken by App-Key

                ValidateIssuer = false,

                ValidateAudience = false

            };

        });

 

    //< CORS >

    //*allow calls from AngularUI

    builder.Services.AddCors(options => options.AddPolicy(name: "FrontendUI", policy => { policy.WithOrigins(url_FrontEnd).AllowAnyMethod().AllowAnyHeader(); }));

    //</ CORS > 

 

//==</ Builder >==

#endregion //==</ Builder.Configure >==

 

#region //==< APP >==

//==< APP >==

var app = builder.Build();

 

// Configure the HTTP request pipeline.

if (app.Environment.IsDevelopment())

{

    app.UseSwagger();

    app.UseSwaggerUI();

}

 

//< CORS >

app.UseCors("FrontendUI");

//</ CORS >

 

 

app.UseHttpsRedirection();

 

app.UseAuthentication();  //*Get User

app.UseAuthorization();

 

app.MapControllers();

 

app.Run();

//==</ APP >==

#endregion //==</ APP >==