Přihlášený uživatel je ztracen mezi úhlovou a c#

0

Otázka

Dělám poprvé aplikaci s autorizací a mám trochu problém. Jsem pomocí úhlové + asp.net default auth, můj rámci dědictví, vypadá takto:

public class CoffeeContext : IdentityDbContext<User, UserRole, int>

UserRole je prázdná třída, která dědictví z IdentityRole < int >. Uživatel je také prázdná třída, která dědictví z IdentityUser < int >.

To je, jak můj UsersControllerClass vypadá:

    [ApiController]
    [Route("users")]
    public class UsersController : ControllerBase
    {
        private readonly SignInManager<User> _signInManager;
        private readonly UserManager<User> _userManager;

        public UsersController(SignInManager<User> signInManager, UserManager<User> userManager)
        {
            _signInManager = signInManager;
            _userManager = userManager;
        }

        [HttpPost]
        [Route("Login")]
        public async Task<IActionResult> Login(UserDto userDto)
        {
            if (ModelState.IsValid)
            {
                var result = await _signInManager.PasswordSignInAsync(userDto.Email, userDto.Password, false, false);
                if (result.Succeeded)
                {
                    return Ok();
                }
                else
                {
                    return BadRequest();
                }
            }

            return Ok();
        }

        [HttpPost]
        [Route("Register")]
        public async Task<IActionResult> Register(UserDto userDto)
        {
            if (ModelState.IsValid)
            {
                var user = new User() {UserName = userDto.Email, Email = userDto.Email};
                var result = await _userManager.CreateAsync(user, userDto.Password);
                if (result.Succeeded)
                {
                    return Ok();
                }
            }

            return BadRequest();
        }

        [HttpGet]
        [Route("Logout")]
        public async Task<IActionResult> Logout()
        {
            if (ModelState.IsValid)
            {
                await _signInManager.SignOutAsync();
            }

            return Ok();
        }
    }

UserDto má 2 vlastnosti: string Email, string Heslo. Mám několik tříd, které mají id uživatele vlastnost. Například recept:

 [ApiController]
    [Route("Recipes")]
    public class RecipesController : ControllerBase
    {
        private readonly IRecipeService _recipeService;
        private readonly Microsoft.AspNetCore.Identity.UserManager<User> _userManager;

        public RecipesController(IRecipeService recipeService, Microsoft.AspNetCore.Identity.UserManager<User> userManager)
        {
            _recipeService = recipeService;
            _userManager = userManager;
        }

        [HttpPost]
        public async Task<IActionResult> CreateRecipe(RecipeDto recipeDto)
        {
            var userId = IdentityExtensions.GetUserId(User.Identity);
            recipeDto.UserId = int.Parse(userId);
            await _recipeService.CreateRecipe(recipeDto);
            return CreatedAtAction(nameof(GetRecipeById), new { Id = recipeDto.Id }, recipeDto);
        }

Jak můžete vidět jsem stále userId tím, IdentityExtension.GetUserId();

Když jsem testování této metody s swagger (první přihlášení pomocí metody od uživatele správce a pak CreateRecipe) vše funguje v pořádku, to dostane přímo id aktuálně přihlášení uživatele. Problém je, že když zkusím použít tu metodu přes frontend s úhlovou. To je, jak moje přihlašovací modul vypadá takto:

export class LoginComponent implements OnInit {
  userForm! : FormGroup;
  user! : LoginModel;
  subbmited = false;
  constructor(private formBuilder: FormBuilder, private userService: UserService) { }

  ngOnInit(){
    this.userForm = this.formBuilder.group({
      email: ['', Validators.required],
      password: ['', Validators.required]
    })
  }

  get Email(){
    return this.userForm.get('email');
  }
  get Password(){
    return this.userForm.get('password');
  }

  onSubmit(){
    this.user = this.userForm.value;
    this.userService.LogIn(this.user).subscribe(res => { console.log(res)});
  }

userService, hodnoty prošel loginComponent jsou správné (registr metoda je v pořádku):

export class UserService {
  readonly ApiUrl = "https://localhost:44331/users"
  constructor(private http: HttpClient) { }

  LogIn(loginModel: LoginModel){
    return this.http.post(this.ApiUrl + '/Login', loginModel, this.generateHeaders());
  }
  Register(loginModel: RegisterModel){
    return this.http.post(this.ApiUrl + '/Register', loginModel, this.generateHeaders());
  }
  private generateHeaders = () => {
    return {
      headers: new HttpHeaders({
        "Content-Type": "application/json",
      }),
    };
  }; 
}

A to je, jak jsem přidat recept:

addRecipe(){
    var val = {
      id:this.RecipeId,
      name:this.RecipeName,
      recipeBody:this.RecipeBody,
      userId: 0,
      intendedUse:this.RecipeIntentedUse,
      coffeeId:this.RecipeCoffeeId
    };
    this.service.createRecipe(val).subscribe(res=>{
      alert(res.toString());
    });
  }

Hodnoty ze vstupů jsou správné, a jsem si nastavit userId na 0, protože to bude nahrazen v každém případě v backend (nebo alespoň myslím, že by mělo). Nakonec dostávám Http status: 500, Hodnota nemůže být null. Když jsem zkontrolovat s debbuging jak userId hodnota vypadá v backend: debug

Jak můžete vidět aktuálně přihlášeného uživatele Id null, což předpokládám znamená, že neexistuje žádný přihlášení uživatelé. Jak to mohu opravit?

Edit: recept.komponenta.ts:

import { Component, OnInit } from '@angular/core';
import { SharedService } from '../shared/shared.service';

@Component({
  selector: 'app-recipe',
  templateUrl: './recipe.component.html',
  styleUrls: ['./recipe.component.css']
})
export class RecipeComponent implements OnInit {
  ModalTitle:string="";
  recipe: any;
  ActiveAddEdditRecipe:boolean=false;
  constructor(private service:SharedService) { }

  RecipeList: any = [];
  
  ngOnInit(): void {
    this.refreshRecipeList();
  }

  refreshRecipeList(){
    this.service.getRecipes().subscribe(data => {
      this.RecipeList=data;
    })
  }
  addClick(){
    this.recipe={
      id:0,
      name:"",
      recipeBody:"",
      userId:"",
      intendedUse:"",
      coffeeId:""
    }
    this.ModalTitle="Add recipe";
    this.ActiveAddEdditRecipe=true;
  }

  editClick(recipeEdit: any){
    this.recipe=recipeEdit;
    this.ModalTitle="Edit recipe";
    this.ActiveAddEdditRecipe=true;
  }

  closeClick(){
    this.ActiveAddEdditRecipe=false;
    this.refreshRecipeList();
  }

  deleteClick(recipeDelete: any){
    this.service.deleteRecipe(recipeDelete).subscribe(data => this.refreshRecipeList());
  }

}

html:

<button type="button" class="btn btn-primary float-right m-2" data-bs-toggle="modal" data-bs-target="#exampleModal" 
(click)="addClick()" 
data-backdrop="static" 
data-keyboard="false">
    Add Coffee
  </button>
  
  <div class="modal" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered modal-xl">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="exampleModalLabel">{{ModalTitle}}</h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"
          (click)="closeClick()" (click)="refreshRecipeList()">
        </button>
        </div>
        <div class="modal-body">
          <app-add-edit-recipe [recipe]="recipe" *ngIf="ActiveAddEdditRecipe"></app-add-edit-recipe>
        </div>
      </div>
    </div>
  </div>

 <div class="wrapper">

    <header>
        <h1>Recipe</h1>
    </header>
        
<section class="columns" *ngFor="let recipe of RecipeList"> 
    <div class="column">
        <h2>{{recipe.name}}</h2>
        <p>{{recipe.recipeBody}}</p>
    </div>
</section>  
    

</div>

A AddEditRecipeComponent

  Component({
  selector: 'app-add-edit-recipe',
  templateUrl: './add-edit-recipe.component.html',
  styleUrls: ['./add-edit-recipe.component.css']
})
export class AddEditRecipeComponent implements OnInit {
  @Input() recipe: any;
  RecipeId!: number ;
  RecipeName: string="";
  RecipeBody : string="";
  RecipeUserId : number = 0;
  RecipeIntentedUse: string ="";
  RecipeCoffeeId: string ="";
  CoffeeList: any[] = [];
  constructor(private service : SharedService) { }

  ngOnInit(): void {
    this.RecipeId = this.recipe.id;
    this.RecipeName = this.recipe.name;
    this.RecipeBody = this.recipe.recipeBody;
    this.RecipeUserId = this.recipe.userId;
    this.RecipeIntentedUse = this.recipe.intendedUse;
    this.RecipeCoffeeId = this.recipe.coffeeId;
    this.getCoffeesList();
  }

  addRecipe(){
    var val = {
      id:this.RecipeId,
      name:this.RecipeName,
      recipeBody:this.RecipeBody,
      userId: 1,
      intendedUse:this.RecipeIntentedUse,
      coffeeId:this.RecipeCoffeeId
    };
    this.service.createRecipe(val).subscribe(res=>{
      alert(res.toString());
    });
  }
  updateRecipe(){
    var val = {
      id:this.RecipeId,
      name:this.RecipeName,
      recipeBody:this.RecipeBody,
      userId:this.RecipeUserId,
      intendedUse:this.RecipeIntentedUse,
      coffeeId:this.RecipeCoffeeId
    };
    this.service.updateRecipe(val).subscribe(res=>{
      alert(res.toString());
    });
  }
  getCoffeesList(){
    this.service.getCoffees().subscribe(data => {
      this.CoffeeList = data;
    })
  }
}
<div class ="col-sm-10">
    <input type="text" class="form-control" [(ngModel)]="RecipeName" placeholder="Enter recipe name">
    <input type="text" class="form-control" [(ngModel)]="RecipeBody" placeholder="Enter recipe text">
    <select type="text" class="form-control" [(ngModel)]="RecipeIntentedUse">
        <option value="" disabled selected>Intended Use</option>
        <option value="Espresso">Espresso</option>
        <option value="Aeropress">Aeropress</option>
        <option value="FrenchPress">FrenchPress</option>
        <option value="Chemex">Chemex</option>
        <option value="Dripper">MediDripperum</option>
        <option value="MokaPot">MokaPot</option>
    </select>
    <select type="text" class="form-control" [(ngModel)]="RecipeCoffeeId">
        <option value="" disabled selected>Select coffee</option>
        <option *ngFor="let coffee of CoffeeList" 
        [value]="coffee.id" >{{coffee.name}}</option>
    </select>
</div>
Přidat Aktualizace
angular asp.net c#
2021-11-23 19:55:13
1

Nejlepší odpověď

1

Vaše logIn() funkce je nesprávně implementováno. To neodesílá žádné ověřování mailů, že je důvod, proč to nefunguje. Nechápu, co se děje s vaším kódem, ale za předpokladu, že vaše implementace funguje perfektně, to je to, jak bych to udělal:

Myslím, že to, co byste měli udělat, je vytvořit Auth Interceptor a nastavení všechny Http požadavky na váš Úhlové aplikaci zahrnují autorizační hlavičky. Zkuste to (za Předpokladu, že jste použili BasicAuth): Na své login.ts modul

export class LoginComponent implements OnInit {
  userForm! : FormGroup;
  email : any;
  password: any;
  encodedValues: any;
  subbmited = false;
  constructor(private formBuilder: FormBuilder, private userService: UserService) { }

  ngOnInit(){
    this.userForm = this.formBuilder.group({
      email: ['', Validators.email],
      password: ['', Validators.required]
    })
  }

  getEmail(event:any){
    this.email = event.target.value;
  }
  getPassword(event:any){
    this.password = event.target.value;
  }

  onSubmit(){
    this.http.post("YOUR API ENDPOINT", this.userForm.getRawValue()).subscribe((res:any)=>{
      this.encodedValues = btoa(this.email +":"+ this.password),
      sessionStorage.setItem("encodedValues", this.encodedValues)
    })

na své login.html soubor, změnit své vstupy zahrnují události změny:

<input type="text" formControlName="email" (change)="getEmail($event)">
<input type="text" formControlName="password" (change)="getPassword($event)">

To bude ukládat vaše autentizační údaje ve vašem prohlížeči skladování, a bude předán jako záhlaví AuthInterceptor

Generovat Ověřovací interceptor:

ng g interceptor AuthInterceptor

Na své AuthInterceptor souboru přidejte tento windguru váš autorizační údaje a předat je jako záhlaví na každé :

intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    const token = localStorage.getItem("encodedValues")
    request = request.clone({
      setHeaders: {
        Authorization: `Basic ${token}`
      }
    });
    return next.handle(request);
  }
}
export const authInterceptorProviders = [
  { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
];

Konečně, na přidání receptu, laskavě sdílet celý .ts takže můžu mít něco na práci s

EDIT

Vaše service.ts soubor a RecipeComponent soubor vypadá správně.

Pokud jste přidali vaše AuthInterceptor jak je uvedeno výše, pak jít do vaší aplikace.modul.ts a přidat to na poskytovatele.

providers: [ { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } ],

To bude nastavit záhlaví na všechny HTTP požadavky

To by mělo fungovat

2021-11-25 07:57:01

Ahoj, mám editovat hlavní příspěvek s receptem.ts a AddEditRecipe.ts
Taxyy

Udělal jsem úpravy na můj původní příspěvek
Kibé M.C

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................