简体   繁体   English

使用 Rails 和 React 进行用户身份验证

[英]User authentication using Rails and React

I've been trying to figure out how to fix my authentication using Ruby on Rails and React.我一直在试图弄清楚如何使用 Ruby on Rails 和 React 修复我的身份验证。 I have been able to login but it automatically logs out whenever I refresh the page.我已经能够登录,但每当我刷新页面时它会自动注销。 What am I missing here?我在这里想念什么?

My SesssionsController: Checks credentials and also logout feature included我的 SessionsController:检查凭据并包括注销功能

    class SessionsController < ApplicationController
    def create
       user = User.find_by(username: params[:username])
       if user && user.authenticate(params[:password])
        session[:user_id] = user.id
        render json: user, status: :created
       else
        render json: {error: {login: "invalid username or password"}}, status: :unauthorized
       end
    end

    def destroy
        session.delete :user_id
        head :no_content
    end
end

Login Frontend (React): This is where users enters their credentials and send it to my sessions controller to check if the credential is valid.登录前端(React):这是用户输入他们的凭据并将其发送到我的会话控制器以检查凭据是否有效的地方。

import React, {  useState } from 'react';
import {Link, useNavigate} from 'react-router-dom';
import './style/login.css';

function Login({setUser}) {
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const navigate = useNavigate();

  function handleSubmit(e) {
    e.preventDefault();
    fetch("http://localhost:3000/login", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ username:username, password:password }),
    })
      .then((r) => r.json())
      .then((user) => setUser(user));
      navigate("/")
  }
  
  return (
    <div className='login_wrapper'>
    <h1>Login</h1> 
    <form className='login_form' onSubmit={handleSubmit}>
      <input
        type="text"
        value={username}
        placeholder="Username"
        onChange={(e) => setUsername(e.target.value)}
      /><br/>
      <input
        type="password"
        value={password}
        placeholder="Password"
        onChange={(e) => setPassword(e.target.value)}
      /><br/>
      <button className="login_btn" type="submit">Login</button>
    </form>
    <br/>
    <div><Link to='/signup'>First time? Register Now!</Link></div>
    </div>
  );
}
export default Login

App.js: storing user data in useState App.js:在useState中存储用户数据

import './App.css';
import React, { useEffect, useState } from 'react';
import { Route, Routes} from "react-router-dom";
import Home from './components/Home';
import Login from './components/Login';
import Signup from './components/Signup';
import Navbar from './components/Navbar';

function App() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetch("http://localhost:3000/auth")
    .then((r) => {
      if (r.ok) {
        r.json()
        .then((user) => setUser(user));
      }
    });
  }, []);

  return(
    <>  
    <Navbar user={user} setUser={setUser} />
    <Routes>
      <Route exact path="/" element={<Home user={user}/>}></Route>
      <Route exact path="/login" element={<Login setUser={setUser} />}></Route>
      <Route exact path="/signup" element={<Signup setUser={setUser}/>}></Route>
    </Routes>
    </>
  )
}

export default App

When I log in, it doesn't save any sessions to the browser - why is this?当我登录时,它不会将任何会话保存到浏览器 - 这是为什么呢? Here's the image:这是图像:

反应前端

My react is quite rusty, but you might find these helpful:我的反应很生疏,但你可能会发现这些很有帮助:

Googling some variation of rails app with react not setting session cookie will probably also get you where you need to go.谷歌搜索一些rails app with react not setting session cookie可能也会让你到达你需要去的地方。

I personally prefer using Devise for authentication, since it is easy to set up and also easily customizable.我个人更喜欢使用Devise进行身份验证,因为它易于设置且易于定制。

If you want, you can pass current_user (Devise's authentication variable, which is the currently logged in user) as a prop to your React components.如果您愿意,您可以将current_user (Devise 的身份验证变量,即当前登录的用户)作为道具传递给您的 React 组件。 Alternatively, you can pass instance variables to each component, and possibly pass them conditionally depending on authentication status.或者,您可以将实例变量传递给每个组件,并可能根据身份验证状态有条件地传递它们。

For example, if you want to show posts and comments to authenticated users, but non-authenticated users should only see the first comment on a post, you could do the following on your controller:例如,如果您想向经过身份验证的用户显示帖子和评论,但未经过身份验证的用户只能看到帖子的第一条评论,您可以在控制器上执行以下操作:

@posts = Post.all
if current_user
  @comments = Comment.all
else
  @comments = Comment.first
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM