由于CORS,Angular授权不起作用

时间:2019-10-08 09:20:53

标签: angular cors

我有一个带有登录和授权的角度项目,问题是授权不适用于错误消息Access to XMLHttpRequest at 'https://myserver/api/auth' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

我已经阅读了有关此主题的几个问题,主要解决方案是直接在浏览器中或在扩展程序的帮助下禁用CORS。是否有可能以其他方式解决此问题,也许有一些角度代码?

这是我的login.ts组件:

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { first } from 'rxjs/operators';

import { AuthenticationService } from '@services/auth.service';

@Component({
  selector: 'app-login-page',
  templateUrl: './login-page.component.html',
  styleUrls: ['./login-page.component.css']
})
export class LoginPageComponent implements OnInit {
  loginForm: FormGroup;
  loading = false;
  submitted = false;
  returnUrl: string;
  error = '';

  constructor(
    private formBuilder: FormBuilder,
    private route: ActivatedRoute,
    private router: Router,
    private authenticationService: AuthenticationService
  ) {
    // redirect to home if already logged in
    if (this.authenticationService.currentUserValue) {
      this.router.navigate(['/']);
    }
  }

  ngOnInit() {
    this.loginForm = this.formBuilder.group({
      username: ['', Validators.required],
      password: ['', Validators.required]
    });

    this.registerForm = this.formBuilder.group({
      email: [''],
      password: [''],
      first_name: [''],
      last_name: [''],
      phone: ['']
    });

    // get return url from route parameters or default to '/'
    this.returnUrl = this.route.snapshot.queryParams['/feed'] || '/';
  }

  // convenience getter for easy access to form fields
  get f() { return this.loginForm.controls; }

  onLogin() {
    this.submitted = true;

    // stop here if form is invalid
    if (this.loginForm.invalid) {
      return;
    }

    this.loading = true;
    this.authenticationService.login(this.f.username.value, this.f.password.value)
      .pipe(first())
      .subscribe(
        data => {
          this.router.navigate([this.returnUrl]);
        },
        error => {
          this.error = error;
          this.loading = false;
        });
  }
}

和auth.service.ts:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators';

import { environment } from '../../environments/environment';
import { User } from '@models/user.model';

@Injectable({ providedIn: 'root' })
export class AuthenticationService {
  private currentUserSubject: BehaviorSubject<User>;
  public currentUser: Observable<User>;

  constructor(private http: HttpClient) {
    this.currentUserSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem('currentUser')));
    this.currentUser = this.currentUserSubject.asObservable();
  }

  public get currentUserValue(): User {
    return this.currentUserSubject.value;
  }

  login(username: string, password: string) {
    return this.http.post<any>(`${environment.apiUrl}/api/auth`, { username, password })
      .pipe(map(user => {
        // store user details and jwt token in local storage to keep user logged in between page refreshes
        localStorage.setItem('currentUser', JSON.stringify(user));
        this.currentUserSubject.next(user);
        return user;
      }));
  }

  logout() {
    // remove user from local storage to log user out
    localStorage.removeItem('currentUser');
    this.currentUserSubject.next(null);
  }
}

也许我可以通过在请求中添加标头来避免这种行为?感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

是的,禁用CORS可能很危险-在浏览编码提示时忘记多次启用它。我使用代理解决了这个问题。

  1. 在项目的根文件夹中创建代理配置文件,例如。具有内容的proxy.conf.json:

GitCommandNotFound: Cmd('git') not found due to: WindowsError('[Error 267] The directory name is invalid') cmdline: git pull

如果端点为HTTPS,则将secure设置为true;如果HTTP,则将false设置为false。以上设置假定您的API位于example.com的/ api / v1中。进行相应的调整。

  1. 将package.json中的启动命令修改为如下形式:

{ "/api/v1": { "target": "https://www.example.com/", "secure": true, "changeOrigin": true } }

该代理仅适用于本地主机。编译后的代码不会调用proxy.conf.json。