Безопасность - проверка подлинности по паспорту Laravel с помощью первого приложения ReactJS Frontend и React-Native - PullRequest
0 голосов
/ 02 ноября 2018

Я создал бэкэнд Laravel с API. Кроме того, я добавил паспорт Laravel для аутентификации.

Сейчас я хочу получить доступ к API через приложение ReactJS Frontend и приложение React-Native. Приложение ReactJS находится на том же сервере, что и серверная часть Laravel.

Теперь я ищу лучший способ соединить все с лучшей безопасностью.

Я искал и проверял учебники, HowTos, ... уже более недели, и я не знаю, что лучше.

Прямо сейчас моя «установка» из-за некоторых потоков и тому подобного:

Я проверил документацию Laravel и несколько HowTos и внедрил Password Grant Client в своем приложении:

public function login(Request $request){

      $http = new GuzzleHttp\Client;

      $response = $http->post(env('APP_URL') . '/oauth/token', [
        'form_params' => [
          'grant_type' => 'password',
          'client_id' => env('PASSWORD_CLIENT_ID'),
          'client_secret' => env('PASSWORD_CLIENT_SECRET'),
          'username' => $request->input('email'),
          'password' => $request->input('password'),
          'scope' => '',
        ],
      ]);

      $responseJSON = json_decode($response->getBody(), true);
      $output = array(
        'access_token' => $responseJSON['access_token'],
        'expires_in' => $responseJSON['expires_in']
      );

      return response($output)
                ->header('Content-Type', 'application/json')
                ->cookie('refreshToken', $responseJSON['refresh_token'], 14400, null, null, true, true);
    }

и для обновления токена:

public function tryRefresh(Request $request) {
      $http = new GuzzleHttp\Client;

      $refreshToken = $request->cookie('refreshToken');

      $response = $http->post(env('APP_URL') . '/oauth/token', [
        'form_params' => [
        'grant_type' => 'refresh_token',
        'refresh_token' => $refreshToken,
        'client_id' => env('PASSWORD_CLIENT_ID'),
        'client_secret' => env('PASSWORD_CLIENT_SECRET'),
        'scope' => '',
        ],
      ]);

      $responseJSON = json_decode($response->getBody(), true);
      $output = array(
        'access_token' => $responseJSON['access_token'],
        'expires_in' => $responseJSON['expires_in']
      );

      return response($output)
                ->header('Content-Type', 'application/json')
                ->cookie('refreshToken', $responseJSON['refresh_token'], 14400, null, null, true, true);
    }

Токен доступа установлен на 30 минут, а токен обновления - на 10 дней. Все работает, но я не знаю, хорошая ли это практика, потому что:

  • Я прочитал, что приложения JS не могут безопасно сохранить токен доступа
  • Жетон обновления не должен сохраняться в куки
  • Laravel предоставляет что-то для JS Frontends
  • (и // или) Для использования API в качестве стороннего приложения эта процедура не требуется

Таким образом, мой вопрос: что является хорошим / лучшим методом для моего типа использования, поэтому аутентификация безопасна и работает как на веб-приложении ReactJs, так и на мобильном приложении React-Native.

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

Идея заключается в следующем:

  1. Создать токен на бэкэнде
  2. Отправьте токен клиенту при входе в систему (в моем приложении Vue.js срок действия установлен на 1 год) и сохраните его в файлах cookie с параметром secure, а не httpOnly (это никогда не передаст значение cookie в клиент)
  3. Передайте токен как Authorization заголовок на сервер от вашего клиента, я использую axios , так что это просто, как request.headers.common['Authorization'] = `Bearer ${token}`;
  4. Реализовать логику обновления токенов на бэкэнде, нет необходимости хранить ее на стороне клиента, в основном, когда истекает срок действия вашего основного токена, следующий запрос к серверу с токеном с истекшим сроком действия должен либо обновить его, либо перенаправить пользователя обратно на страницу входа (я выбрал второй подход для устранения возможных проблем с плохой логикой на стороне сервера)

Вот примеры моего входа в систему и выхода из системы методов:

/**
 * Authenticate user.
 *
 * @param Request $request
 *
 * @return JsonResponse
 */
public function authenticate(Request $request): JsonResponse
{

    $validator = Validator::make($request->all(), [
        'email' => 'required|string|email',
        'password' => 'required|string|min:8',
        'remember_me' => 'boolean',
    ]);

    if ($validator->fails()) {
        return $this->sendError('errors.invalid_request', $validator->errors()->toArray(), Response::HTTP_BAD_REQUEST);
    }

    $credentials = request(['email', 'password']);

    if (!\Auth::attempt($credentials)) {
        return $this->sendError('errors.account.invalid_credentials', [], Response::HTTP_FORBIDDEN);
    }

    $user = $request->user();
    if (!$user->active) {
        return $this->sendError('errors.account.inactive', [], Response::HTTP_CONFLICT);
    } elseif (null !== $user->deleted_at) {
        return $this->sendError('errors.account.deleted', [], Response::HTTP_CONFLICT);
    }

    $createdToken = $user->createToken(sprintf('Access token for %s', $user->username));
    $token = $createdToken->token;

    if ($request->remember_me) {
        $token->expires_at = now()->addYears(1);
    }

    $token->save();

    return $this->sendResponse('account.status.authenticated', [
        'access_token' => $createdToken->accessToken,
        'token_type' => 'Bearer',
        'expires_at' => Carbon::parse($createdToken->token->expires_at)->toDateTimeString(),
    ]);
}

/**
 * Logout user and revoke access token.
 *
 * @param Request $request
 *
 * @return JsonResponse
 */
public function logout(Request $request): JsonResponse
{
    $request->user()->token()->revoke();

    return $this->sendResponse('account.status.logged_out');
}
0 голосов
/ 02 ноября 2018

Учитывая рамки, которые вы хотите использовать, аутентификация на основе токенов, которую вы внедрили IS хорошая практика.

Вы также можете посмотреть JWT как альтернативу аутентификации типа «Предоставление пароля».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...