Laravel socialite + vue spa возвращает токен доступа клиенту

Как я могу вернуть клиенту токен доступа, который я получаю при обратном вызове светской львицы? Мне нужно вернуть эти данные в vue, чтобы пользователь вошел в систему. данные токена

Это мой код в vue, чтобы получить URL-адрес перенаправления

googleLogin(){
      const self = this;

      let socialLogin = {
          name: 'google'
      };

      self.$http.post(`api/googleLogin`, socialLogin)
          .then(response => {
              console.log('GOOGLE LOGIN RESPONSE ', response.body);
              window.location = response.body;
          })

  }

И для бэкэнда

 public function googleLogin(Request $request){

    $socialType = $request->name;

    return response()->json(
        Socialite::driver($socialType)
            ->with(['social_type' => $socialType])
            ->stateless()
            ->redirect()
            ->getTargetUrl()
    );
}

public function googleLoginCallback(){

    $http = new \GuzzleHttp\Client;

    $user = Socialite::with('google')->stateless()->user();

    $userCredentials = [
        'token' => $user->token,
        'refreshToken' => $user->refreshToken,
        'expiresIn' => $user->expiresIn,
    ];


    $response = $http->post(env('LOGIN_ENDPOINT'), [
        'form_params' => [
            'grant_type' => 'social',
            'client_id' => env('CLIENT_ID'),
            'client_secret' => env('CLIENT_SECRET'),
            'network' => 'google',
            'access_token' => $userCredentials['token'],
        ]
    ]);
    return json_decode((string) $response->getBody(), true);
}

person jdc    schedule 15.08.2018    source источник


Ответы (1)


Я работал над чем-то похожим и нашел решение. Код основан на этой замечательной стартовой теме: https://github.com/cretueusebiu/laravel-vue-spa

--

В googleLoginCallback (), предполагая, что вы используете аутентификацию Passport API, вы можете попробовать это для контроллера:

public function googleCallback()
    {
        $provider = 'google';

        $user = Socialite::driver($provider)->stateless()->user();

        /* HERE CREATE USER WITH YOUR APP LOGIC. If email is unique... */

        // Login the created user
        Auth::login($user, true);

        // Get the username (or wathever you want to return in the JWT).
        $success['name'] = Auth::user()->name;
        // Create a new access_token for the session (Passport)
        $success['token'] = Auth::user()->createToken('MyApp')->accessToken;

        // Create new view (I use callback.blade.php), and send the token and the name.
        return view('callback', [
            'name' => $success['name'],
            'token' => $success['token'],
        ]);
    }

Для представления callback.blade.php вам нужно только отправить запрошенный токен и имя пользователя в приложение Vue. Для этого вы можете использовать метод window.postMessage (), который позволяет отправлять данные между окнами, iframe ...

<html>
<head>
  <meta charset="utf-8">
  <title>Callback</title>
  <script>
    window.opener.postMessage({ token: "{{ $token }}", name: "{{ $name }}" }, "YOUR DOMAIN");
    window.close();
  </script>
</head>
<body>
</body>
</html>

И, наконец, это моя логика для компонента Login в приложении vue:

export default {
        // Waiting for the callback.blade.php message... (token and username).
        mounted () {
          window.addEventListener('message', this.onMessage, false)
        },

        beforeDestroy () {
          window.removeEventListener('message', this.onMessage)
        },

        methods : {
            // This method call the function to launch the popup and makes the request to the controller. 
            loginGoogle () {
              const newWindow = openWindow('', 'message')
              axios.post('api/login-google')
                    .then(response => {
                      newWindow.location.href = response.data;
                    })
                    .catch(function (error) {
                      console.error(error);
                    });
              },
              // This method save the new token and username
              onMessage (e) {
                if (e.origin !== window.origin || !e.data.token) {
                  return
                }
                localStorage.setItem('user',e.data.name)
                localStorage.setItem('jwt',e.data.token)

                this.$router.go('/board')
              }
        }
    }

    // The popup is launched.

    function openWindow (url, title, options = {}) {
      if (typeof url === 'object') {
        options = url
        url = ''
      }

      options = { url, title, width: 600, height: 720, ...options }

      const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : window.screen.left
      const dualScreenTop = window.screenTop !== undefined ? window.screenTop : window.screen.top
      const width = window.innerWidth || document.documentElement.clientWidth || window.screen.width
      const height = window.innerHeight || document.documentElement.clientHeight || window.screen.height

      options.left = ((width / 2) - (options.width / 2)) + dualScreenLeft
      options.top = ((height / 2) - (options.height / 2)) + dualScreenTop

      const optionsStr = Object.keys(options).reduce((acc, key) => {
        acc.push(`${key}=${options[key]}`)
        return acc
      }, []).join(',')

      const newWindow = window.open(url, title, optionsStr)

      if (window.focus) {
        newWindow.focus()
      }

      return newWindow
    }

</script> 

Надеюсь, это вам поможет!

person asiermusa    schedule 17.01.2019