Правильный способ реализовать Github OAuth в клиентском приложении?

#javascript #node.js #reactjs #oauth

#javascript #node.js #reactjs #oauth

Вопрос:

Я добавляю OAuth в свое клиентское приложение github. У меня успешно возвращен окончательный токен аутентификации, но я чувствую, что взломал свой рабочий процесс.

Текущий поток архитектуры:

1) Пользователь нажимает href ссылку из компонента, чтобы перейти к начальному маршруту OAUTH

2) Извлеките токен из Github для идентификации пользователя

3) Github перенаправляет на мой серверный маршрут, а мой серверный маршрут отправляет дополнительный запрос POST на /access_token страницу запроса с client_secret , id и code с приведенного выше шага.

4) Наконец, я перенаправляю с вышеуказанного маршрута обратно в свой пользовательский интерфейс и устанавливаю параметр URL в процессе

5) В componentDidMount я удаляю конечный токен аутентификации из window.url и устанавливаю его в моем состоянии

Примечание: Я планирую сохранить токен в Redux позже, но это базовый уровень того, что я делаю.

Фактический код

Сервер

 app.get("/login", async (req, res) => {
  // Get the identity token from GitHub origin
  return await axios
    .post("https://github.com/login/oauth/access_token", {
      code: req.query.code,
      client_id: process.env.CLIENT_ID,
      client_secret: process.env.CLIENT_SECRET
    })
    .then(async resp => {
      // Little hack to parse out the query params into an object 
      let data = await url.parse("http://parse.com?"   resp.data, {
        parseQueryString: true
      }).query;

      res.redirect(
        url.format({
          pathname: Environment.getUrl(),
          query: {
            token: data.access_token
          }
        })
      );
    });
});
  

Компонент аутентификации пользовательского интерфейса

 export default class GithubAuthentication extends React.Component {
  state = {
    authToken: "DATA"
  };

  componentDidMount() {
    let currUrl = window.location.href;
    this.setState({ authToken: currUrl.split("token=")[1] });
  }

  render() {
    return (
      <React.Fragment>
        <a href="https://github.com/login/oauth/authorize?client_id=b5cd37110eb31620aad7">
          {this.state.authToken ? "Logout" : "Login With Github"}
        </a>
        <span>{this.state.authToken}</span>
      </React.Fragment>
    );
  }
}
  

Вопросы

1) Единственное, чего я не смог понять, это сделать href ссылку контролируемым компонентом и фактически ввести URL-адрес аутентификации чем-то вроде SuperAgent или Axios . Вместо этого я вынужден использовать эту href ссылку, не уверен почему.

2) Действительно ли это разумный способ получения конечного токена аутентификации?

Ответ №1:

Что касается вопроса 2, с точки зрения безопасности, лучше хранить токен доступа на стороне сервера и никогда не отправлять токен на сторону клиента.

Я не смог найти хороших письменных ресурсов, поэтому я хотел бы поделиться этим видео, в котором кратко описывается, как обращаться с токеном доступа.

https://www.youtube.com/watch?v=CHzERullHe8amp;list=PL78z2Z3ZApYcKb-GDQt6ikdN2EDqmKJrTamp;index=12amp;t=419s

Отрывок из видео

  • У нас все еще нет хорошего способа безопасного хранения токена в браузере
  • Сохраняя токен доступа на стороне сервера и используя сессионный файл cookie, вы можете свести к минимуму риск компрометации токена доступа.

Чтобы фактически реализовать этот поток, вы можете использовать cookie-session для генерации сеанса. Вы также можете использовать github-passport для упрощения реализации.

https://github.com/expressjs/cookie-session
https://github.com/jaredhanson/passport-github

Ответ №2:

1) Я думаю, вам следует реорганизовать свое приложение, чтобы вы могли использовать компонент вместо ссылки href. Вы бы узнали, аутентифицированы вы или нет, основываясь на значении свойства state. Это значение может быть передано в качестве prop вашему компоненту, в который вы бы поместили логику аутентификации? «Logout»: «Войти» или что-нибудь еще.

2) поток в порядке, но вы должны убедиться, что выполняете проверку токена на стороне сервера, поскольку легко просто щелкнуть переключателем в пользовательском интерфейсе и очень легко притвориться, что вы аутентифицированы.

Комментарии:

1. Я получал проблемы с перекрестным источником при использовании компонента вместо href. Не совсем уверен, почему это происходит.

2. Проблема CORS возникает, если вы выполняете вызов js на другой сервер, и этот сервер не разрешает нежелательные вызовы из неизвестного приложения, которое включено по умолчанию, поэтому ваш сервер должен разрешать запросы из вашего клиентского домена в Access-Control-Allow-Origin заголовке