Devise - одно из самых популярных решений аутентификации для Rails из-за его высокой универсальности, ясной документации и большого сообщества. Однако мне не удалось найти никаких руководств или документации по его интеграции с React в гем Webpacker, поэтому я решил выложить свое собственное решение.
Я предполагаю, что вы можете настроить приложение Rails с React через гем Webpacker самостоятельно, и что у вас уже установлен Devise с созданной, перенесенной и готовой к работе пользовательской моделью. Я также предполагаю, что вы имеете базовое представление о React и жизненном цикле React.
Во-первых, вам понадобится компонент-контейнер. Скорее всего, это будет ваш файл App.jsx, потому что вы захотите передать информацию о текущем пользователе всем остальным вашим компонентам через свойства. Мы будем использовать Axios, поэтому убедитесь, что вы установили его на yarn, прежде чем мы начнем.
class App extends React.Component { constructor(){ super(); this.state = { currentUser: null } this.updateCurrentUser = this.updateCurrentUser.bind(this); } componentDidMount(){ let that = this axios.get('/users/check_for_user',{ }) .then(function(response){ if(response.data.email){ that.setState({ currentUser: response.data.email }) } else { that.setState({ currentUser: null }) } }) .catch(function(error){ console.log(error); }) } updateCurrentUser(email) { this.setState({ currentUser: email }) } render(){ return ( <div> <Header updateCurrentUser={this.updateCurrentUser}/> </div> ) } }
В этом компоненте мы установили состояние по умолчанию на null без пользователя.
Затем у нас есть функция, которая будет вызывать Axios к настраиваемому маршруту, который проверяет, вошел ли пользователь в систему или нет. В моем контроллере Rails я отправляю JSON-версию метода Devise current_user, если кто-то вошел в систему, и пустой пользовательский объект, если кто-то нет. Помещение этого в фазу DidMount жизненного цикла React позволяет пользователю оставаться в системе даже после обновления страницы. Этот вызов позволяет вам использовать Devise с React вместо передачи токенов.
У нас есть функция updateCurrentUser, которую мы на самом деле не будем использовать в этом контейнере, но я поместил ее в этот контейнер, потому что она будет использоваться в нескольких компонентах, поэтому в дальнейшем к ней будет легко получить доступ через реквизиты, если она останется здесь.
Header.jsx
class Header extends React.Component { constructor(props){ super(props); if (this.props.currentUser == null){ this.state = { page:"login" } } else{ this.state = { page: "delete" } } this.changePage = this.changePage.bind(this); } changePage(newPage) { this.setState({ page: newPage }) } render() { switch(this.state.page) { case "signup": return <Signup changePage={this.changePage} updateCurrentUser={this.props.updateCurrentUser}/> case "login": return <Login changePage={this.changePage} updateCurrentUser={this.props.updateCurrentUser}/> case "delete": return <Logout changePage={this.changePage} updateCurrentUser={this.props.updateCurrentUser}/> } } }
В этом компоненте я использую переключатель, чтобы изменить, какие компоненты визуализируются. Это связано не столько с аутентификацией, сколько со стилем, поэтому я перейду к компоненту Registration.jsx:
Регистрация.jsx
class Signup extends React.Component { constructor(props){ super(props); this.handleSignup = this.handleSignup.bind(this); } handleSignup(e) { e.preventDefault(); let that = this axios.post('/users', { user: { email: document.getElementById("email").value, password: document.getElementById("password").value, password_confirmation: document.getElementById("password_confirmation").value } }) .then(function(response){ that.props.changePage("delete"); that.props.updateCurrentUser(email); }) .catch(function(error){ console.log(error) }) } render() { return ( <div> <h2>Signup</h2> <form> <input id="email" placeholder="email"/> <input id="password" placeholder="password"/> <input id="password_confirmation" placeholder="retype password"/> <button onClick={this.handleSignup}>Submit</button> </form> <button onClick={() => this.props.changePage("login")}>Back to Login</button> </div> ); }; };
В этом компоненте мы делаем еще один вызов Axios, беря информацию прямо из формы, отображаемой на странице. Devise заполняет за вас большую часть серверной части, поэтому я предполагаю, что вы сможете понять, как отправлять вещи в таком порядке.
Логин выглядит так же, как Регистрация, поэтому я закончу…
Logout.jsx
class Logout extends React.Component { constructor(props){ super(props); this.handleLogout = this.handleLogout.bind(this); } handleLogout(e) { e.preventDefault(); let that = this let email = this.props.currentUser axios.delete('/users/sign_out', { }) .then(function(response){ that.props.changePage("login") }) .catch(function(error){ console.log(error) }) } render() { return ( <button onClick={this.handleLogout}>Sign Out</button> ); }; }
Как видите, интегрировать Devise через Webpacker не так уж сложно для быстрой и простой системы аутентификации, когда вы не хотите связываться с передачей токенов в React.
📝 Прочтите этот рассказ позже в Журнале.
👩💻 Просыпайтесь каждое воскресное утро и слушайте самые интересные истории из области технологий, ожидающие вас в вашем почтовом ящике. Прочтите информационный бюллетень« Примечательно в технологиях .