Laravel 5.6上的Ajax Auth重定向 [英] Ajax Auth redirect on Laravel 5.6

查看:63
本文介绍了Laravel 5.6上的Ajax Auth重定向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个喜欢"按钮会触发Ajax发布,该路由受auth:api中间件保护:

I have a Like button that fires an Ajax Post, this route is protected by auth:api middleware:

myproject/routes/api.php

myproject/routes/api.php

Route::group(['middleware' => ['auth:api']], function () {
    Route::post('/v1/like', 'APIController@set_like');
});

通过身份验证的用户单击赞"按钮时,完全没有问题,一切都将顺利进行.但是,当访客单击按钮时,我通过Javascript将他们重定向到登录页面,并在身份验证后将他们重定向到RedirectIfAuthenticated中间件中指定的页面,因此通常重定向到/home. 我对该中间件进行了如下修改:

When an authenticated user clicks the like button, no problem at all, everything works smoothly. But when guests click the button, I redirected them to login page via Javascript and after authentication they are redirected to the page specified in RedirectIfAuthenticated middleware, so usually to /home. I modified that middleware as follows:

myproject/app/Http/Middleware/RedirectIfAuthenticated.php

myproject/app/Http/Middleware/RedirectIfAuthenticated.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class RedirectIfAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->check()) {
            return redirect()->intended('/home');
        }
        return $next($request);
    }
}

我的Ajax呼叫是这样:

My Ajax call is this:

var toggleLike = function(){
    var token = USER_TOKEN; //javascript variable
    var current_type = $(thisLikeable).attr("data-type");
    var current_id = $(thisLikeable).attr("data-id");
    var jqxhr = $.post( APP_URL + "/api/v1/like", {api_token: token, type: current_type, id: current_id}, function(data) {
        setLikeAppearance(data.message);
    })
    .fail(function(xhr, status, error){
        if (xhr.status == 401) {
            window.location = APP_URL + "/login" ;
        }
    });
};

问题出在这里,意图是()函数,对于Ajax调用,该函数没有存储正确的会话变量,而且我也没有弄清楚如何正确设置它. 我显然缺少明显的东西,任何人都可以帮忙吗? 干杯!

The problem here's the intended() function, which for Ajax calls is not storing the correct session variable and I am not figuring out how to set it properly. I am clearly missing something obvious, can anyone help? Cheers!

编辑

我想实现的是这样:

  1. GUEST位于//mysite/blabla
  2. 单击赞"按钮
  3. 被重定向到登录名
  4. 登录(或注册)
  5. 使用已触发的赞"重定向到//mysite/blabla

推荐答案

正在发生的事情是,在API中,会话不是受管理的,换句话说,它是无状态的.因此,会话中间件未在Laravel框架上实现用于API请求.尽管您可以手动添加,但它并非闲置使用.因此,如果API不使用会话并使用重定向,那么由于API和前端可以作为两个单独的应用程序工作,因此fronted对此一无所知.因此,您需要向前端发送响应状态,并让前端像处理ajax一样处理重定向.仅在未经身份验证的情况下删除重定向,然后让API引发未经授权的异常.然后从处理程序中处理未经授权的异常.

What's happening is that in APIs sessions are not managed or in other words it's stateless. So the session middleware is not implemented on Laravel framework for API requests. Though you can manually add, it's not idle to use. So if the API does not use sessions and uses the redirect, fronted does not know about it, as API and frontend work as two separate apps. SO you need to send the frontend the status of the response and let the frontend handle the redirect as you have done with ajax. just remove the redirect if unauthenticated and let the API throw unauthorized exception. then from the handler, handle the unauthorized exception.

这是方法.

将此添加到 app/Exceptions/Handler.php

/**
 * Convert an authentication exception into an unauthenticated response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Illuminate\Auth\AuthenticationException  $exception
 * @return \Illuminate\Http\Response
 */
protected function unauthenticated($request, AuthenticationException $exception)
{
    if ($request->expectsJson()) {
        return response()->json(['error' => 'Unauthenticated.'], 401);
    }

    return redirect()->guest('login');
}

如果请求是json(api请求),这将向用户发送401未经验证的消息,否则(如果是Web请求)将重定向到登录

this will send the user a 401 with message Unauthenticated if the request was json(api request), else(if web request) will redirect to login

检查下面的render方法,或从来源以了解正在发生的事情.当引发未经授权的异常时,我们会告诉您检查请求类型,如果它来自API请求,我们将发送带有401状态代码的json响应.从前端知道,我们可以在看到401状态代码后将用户重定向到登录页面.

check the render method below or check it from source to understanc what's happening. when an unauthorized exception is thrown we are telling to check the request type and if it's from an API request, we are sending a json response with 401 status code. So know from frontend we could redirect the usee to login page after seeing the 401 status code.

来自来源

/**
 * Render an exception into a response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Exception  $e
 * @return \Symfony\Component\HttpFoundation\Response
 */
public function render($request, Exception $e)
{
    if (method_exists($e, 'render') && $response = $e->render($request)) {
        return Router::toResponse($request, $response);
    } elseif ($e instanceof Responsable) {
        return $e->toResponse($request);
    }
    $e = $this->prepareException($e);
    if ($e instanceof HttpResponseException) {
        return $e->getResponse();
    } elseif ($e instanceof AuthenticationException) {
        return $this->unauthenticated($request, $e);
    } elseif ($e instanceof ValidationException) {
        return $this->convertValidationExceptionToResponse($e, $request);
    }
    return $request->expectsJson()
                    ? $this->prepareJsonResponse($request, $e)
                    : $this->prepareResponse($request, $e);
}

编辑后

预期的method()仅适用于Web路由,因为它使用会话来提取预期的路由或手动传递的值.这是预期的()方法.

The intended method() is only for web routes as it uses session to extract the intended route or manually passed value. Here is the intended() method.

/**
 * Create a new redirect response to the previously intended location.
 *
 * @param  string  $default
 * @param  int     $status
 * @param  array   $headers
 * @param  bool    $secure
 * @return \Illuminate\Http\RedirectResponse
 */
public function intended($default = '/', $status = 302, $headers = [], $secure = null)
{
    $path = $this->session->pull('url.intended', $default);

    return $this->to($path, $status, $headers, $secure);
}

要实现重定向至用户所要访问的页面

To achive the redirect to the page the user is comming from you can

1-手动传递带有/login?redirect=like(not the url, just a mapping for /comments/like url)&value=true(true is liked, false is unliked)之类的url的查询,并手动进行处理.

1 - manually pass some queries with url like /login?redirect=like(not the url, just a mapping for /comments/like url)&value=true(true is liked, false is unliked) and handle it manually.

2-从url获取并检查查询参数

2 - get and check the query parameters from url

3-使用to()方法传递预期的url,而不是使用意图的().这是to()方法. (请参阅4以了解推荐的方式)

3 - use to() method to pass the intended url instead of using intended(). here is the to() method. (see 4 to see the recommended way)

/**
 * Create a new redirect response to the given path.
 *
 * @param  string  $path
 * @param  int     $status
 * @param  array   $headers
 * @param  bool    $secure
 * @return \Illuminate\Http\RedirectResponse
 */
public function to($path, $status = 302, $headers = [], $secure = null)
{
    return $this->createRedirect($this->generator->to($path, [], $secure), $status, $headers);
}

4-但是,我建议发送重定向url(我的意思是映射ex:like)作为对前端的响应,并让前端处理重定向.因为仅当网站使用API​​时,API重定向才有效.假设如果您在移动应用程序中使用了相同的api,则想知道API重定向将如何工作.重定向不是API的工作,除非用于OAuth身份验证之类的事情,它将指定重定向URL.

4 - But, I would recommend sending redirect url (i mean the mapping ex: like) as a response to frontend and let the frontend handle the redirecting. as API redirecting will work if the API is used by websites only. Suppose if you are using this same api for a mobile app, wonder how API redirect will work. It's not a work of API to redirect, unless if it's for things like OAuth Authentication, which would have a redirect url specified.

记住要清理url参数以阻止类似XSS的东西.更好的 发送一些值并将其映射到网址.喜欢

remember to sanitize the url params to block XSS like stuff. Better send some values and map it to the urls. Like

[
   //like is mapping
   //comments/like is the actual url

   'like' => 'comments/like'
]

然后从数组中获取映射URL或使用前端映射.

then get the mapping url from array or use frontend mappings.

这篇关于Laravel 5.6上的Ajax Auth重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆