Laravel Sanctum /使用HttpClient的Angular 2 xsrf-cookie

2lpgd968  于 2023-03-04  发布在  Angular
关注(0)|答案(3)|浏览(146)

我正在尝试使用Angular 2Laravel(后端)中的服务。如果使用axios,我可以毫无问题地使用它,但我需要使用HttpClient
我如何翻译这个代码:

const url = `${this.endPoint}/login`;
const urlCsrf = `${this.endPoint}/csrf-cookie`;
const body = { email, password };

axios.defaults.withCredentials = true;

axios.get(urlCsrf).then(() => {
    axios.post(url, body).then((resp) => {
        console.log(resp);
    });
});

像这样的东西,但它的工作:

//this code dont work returns csrf error
this.http.get(urlCsrf).subscribe(() => {
     this.http.post(url, body).subscribe((resp) => {
         console.log(resp);
    });
});
qxsslcnc

qxsslcnc1#

我最近遇到了同样的问题,以下是对我有效的方法:

$data = 'client_id=xxxxxxxxx&client_secret=xxxxxxxxx&grant_type=client_credentials';
$url = "https://xxxxxxxxxxxxxxxxxxxxx.x/xx/xxxxx";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/x-www-form-urlencoded',
    'Content-Length: ' . strlen($data))
);
$contents = curl_exec($ch);
if (curl_errno($ch)) {
  echo curl_error($ch);
  echo "\n<br />";
  $contents = '';
} else {
  curl_close($ch);
}

if (!is_string($contents) || !strlen($contents)) {
echo "Failed to get contents.";
$contents = '';
}
$json = json_encode($contents);
o2rvlv0m

o2rvlv0m2#

该代码翻译为:

const body = {email, password}
this.http.get(urlCsrf).subscribe(() => {
     this.http.post(url, body, { withCredentials: true }).subscribe((resp) => {
         console.log(resp);
    });
});

如果你想用一种更被动的方式来写:

const body = {email, password}
this.http.get(urlCsrf).pipe(
     switchMap(()=> this.http.post(url, body, { withCredentials: true })
  ).subscribe((resp) => console.log(resp));

如果你想把withCredentials应用到所有的请求,你应该看看评论中提到的拦截器。

@Injectable()
export class CredentialsInterceptor implements HttpInterceptor {
  constructor() {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
      return next.handle(req.clone({ withCredentials: true }));
  }
}

然后导入到AppModule

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

ogq8wdun3#

也许我迟到了,但我花了很多时间来寻找这个问题的解决方案,我想与大家分享最后的解决方案,这是正确的我。
我的设置:Angular 15-拉拉威尔10与密室。
Laravel配置:. env文件:添加行会话驱动程序= cookie会话域=本地主机
php文件添加有状态本地主机:4200(用于angular ng服务)

'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
    '%s%s',
    'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1,localhost:4200',
    Sanctum::currentApplicationUrlWithPort()
))),

cors.php为凭据设置为true:

'supports_credentials' => true,
    • 重新启动服务器LARAVEL以应用更改。**

然后,在Angular 应用程序中:
1.定义拦截器如下:
导出类HttpXsrfInterceptor实现了HttpInterceptor {headerName ='X-XSRF-TOKEN';构造函数(私有令牌服务:HttpXsrf令牌提取程序){}
截取(请求:HttpRequest,下一步:HttpHandler):可观察到的{req = req.克隆({具有凭据:真,}); true, });

req.headers.set('withCredentials', 'true');
if (req.method === 'GET' || req.method === 'HEAD') {
  return next.handle(req);
}

const token = this.tokenService.getToken();
// Be careful not to overwrite an existing header of the same name.
if (token !== null && !req.headers.has(this.headerName)) {
  req = req.clone({ headers: req.headers.set(this.headerName, token) });
}

return next.handle(req);

}}
1.在AuthService中,将登录方法设置为:
登录(登录表单:登录表单):可观察{
返回这个. http. get('http://本地主机/sancutum/csrf-cookie'). pipe(switchMap(()=〉{

return this.http
   .post<LoginResponse>(base_url + 'access/login', loginForm)
   .pipe(
     tap((data) => {

       const user = new User(
         data.user.id,
         data.user.firstname,
         data.user.lastname,
         data.user.username,
         data.user.email,
         data.user.created_at
       );
       this.user.next(user);
     })
   )

}),catchError(错误=〉{控制台.错误(错误);返回throwError(错误);));
};
希望这能帮到什么人。

相关问题