بررسی login شدن کاربر قبل از render شدن component لاگین در React

react
reactjs

#1

سلام دوستان
دارم یه spa با react مینویسم
برای این که بررسی کنم اگه کاربر login شده دیگه صفحه ورود render نشه و مستقیم بره تو home چنین کاری کردم

componentWillMount() {
    axios.get('/profile/')
      .then(resp => {
        console.log('true', resp);
        this.setState({isLoggedIn: true});
      })
      .catch(err => {
        console.log('false', err);
        this.setState({isLoggedIn: false});
      });
  }


render() {
    const isLoggedIn = this.state.isLoggedIn;
    if (isLoggedIn) {
      return <Home />
    } else {
    return (
      <form onSubmit={this.handleSubmit}>
        <input type="text" onChange={this.handleUsernameChange} placeholder="username" />
        <input type="password" onChange={this.handlePasswordChange} placeholder="password" />
        <input type="submit" value="Submit" />
      </form>
    );
    }
  }
}

اولش از componentDidMount استفاده کردم و یه ریکوئست میزنم به بک اند که پروفایل کاربر فعلی رو برگردونه که اگه کسی login نشده باشه با ارور مواجه میشه و منم کاری کردم اگه موفقیت آمیز بود isLoggedIn بشه true و اگه به ارور خورد false اما وقتی صفحه رو ریلود میکردم اول یه لحظه خیلی کوتاه صفحه لوگین نمایش داده میشد بعد صفحه home
رفتم سرچ کردم فهمیدم برای این که قبل render شدن یه کاری انجام بشه باید از componentWillMount استفاده کرد ولی نتیجه همچنان همونه!!
کد کامل:

import React, { Component } from 'react';
import axios from 'axios'

import Home from './Home'



class Login extends Component {
  constructor(props) {
    super(props);
    this.state = {username: '', password: ''};

    this.handleUsernameChange = this.handleUsernameChange.bind(this);
    this.handlePasswordChange = this.handlePasswordChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  componentWillMount() {
    axios.get('/profile/')
      .then(resp => {
        console.log('true', resp);
        this.setState({isLoggedIn: true});
      })
      .catch(err => {
        console.log('false', err);
        this.setState({isLoggedIn: false});
      });
  }

  handleUsernameChange(event) {
    this.setState({username: event.target.value});
  }

  handlePasswordChange(event) {
    this.setState({password: event.target.value});
  }

  handleSubmit(event) {
    axios.defaults.withCredentials = true;
    axios.post('/login/', { username: this.state.username, password: this.state.password})
      .then(rv => {
        console.log('Login', rv)
      })
      .catch(err => {
        console.log('Login error', err.response)
      });
    event.preventDefault();
  }


  render() {
    const isLoggedIn = this.state.isLoggedIn;
    if (isLoggedIn) {
      return <Home />
    } else {
    return (
      <form onSubmit={this.handleSubmit}>
        <input type="text" onChange={this.handleUsernameChange} placeholder="username" />
        <input type="password" onChange={this.handlePasswordChange} placeholder="password" />
        <input type="submit" value="Submit" />
      </form>
    );
    }
  }
}

export default Login;


#2

سلام
وقتی شما صفحه رو reload میکنید state از بین میره . برای همین اگر کسی هم لاگین کرده باشه چون state از بین رفته انگار کسی لاگین نکرده برای همین دوباره میره به صفحه لاگین ،‌ بهتره از session استفاده بشه برای ذخیره مقدار تا در زمان reload توسط کاربر از بین نره و در componentWillMount مقدار سشن چک و خونده بشه


#3

نه از اون نظر مشکلی نداره و متوجه میشه یکی لاگین کرده و میره به home
فقط سیستمش اینجوریه که اول login رو باز میکنه بعد چک میکنه کسی لاگین کرده یا نه و بعد بلافاصله صفحه home باز میشه
یه لحظه کوتاهی میره تو لاگین بعدش بررسی میشه که لاگین شده و میره تو home
من میخوام اول بررسی کنه کسی login شده یا نه؟ بعد home یا login رو نمایش بده


#4

امکانش هست چون در componentWillMount دارین درخواست ارسال میکنید تا جوابش بیاد یه مقدار طول میکشه تا state ست بشه قبلش state در render بررسی شده و مقدارش false هست برای همین صفحه لاگین رو نشون میده . بعد که جواب دریافت شد و state مقداردهی شد دوباره متد render اجرا میشه و چک میکنه مبینه طرف لاگین کرده و میره صفحه home ولی اگر از session استفاده کنید زمانیکه کاربر لاگین بکنه و بعد اگر رفرش هم بکنه چون شما مقدار مورد نظرتون بابت لاگین رو از session خوندید و دیگه درخواستی رو ارسال نکردید این تاخیر پیش نمیاد


#5

ممنون میشم کمی بیشتر توضیح بدین که توی react چه جوری باید از session استفاده کنم


#6

برای ست کردن سشن

localStorage.setItem('myData', data);

برای خوندن مقدار سشن

localStorage.getItem('myData');

برای بررسی بهتر state از پلاگین react developer tools استفاده کنید


#7

سلام
این اطلاعات تا کی ذخیره میمونه؟
من نیاز دارم که توی صفحه اصلی یه خوشامد گویی به کار بر داشته باشم و نوع کاربری و اطلاعات دیگه رو نشونش بدم
و میخواستم دوباره توی صفحه اصلی request بزنم و این اطلاعات رو بگیرم اما منطقی تر نیست بعد لاگین هم مقدار متغیر isLoggedIn رو true کنم و هم بقیه اطلاعاتش رو به این شکل نگه دارم که همه جا بتونم استفاده کنم به جای اینکه باز request بزنم تا بفهمم کاربر کیه؟


#8

سشن تا زمانیکه مرورگر کاربر باز باشه ذخیره میمونه . کلا اطلاعات کاربر بهتره توی سشن نباشه . از توکن کاربر که توی سشن ذخیره کردید استفاده کنید و با همون درخواست بزنید اطلاعاتش رو بخونید و بهش نمایش بدین


#9

توکنی وجود نداره :laughing:
در واقع از session authentication دارم استفاده میکنم
چرا میگین بهتره اطلاعات کاربر تو session نباشه؟


#10

برام جالب شد. چرا شما باید بی خیال توکن بشید و اطلاعات کاربر رو ببرید روی سشن . بلخره شما یک بکندی دارید که مثلا می تونه با jwt بیاد یک توکن ایجاد کنه و شما بجای اطلاعات کاربر توکنشو ذخیره کنید که خود توکن شامل مثلا اطلاعاتی مثل شناسه کاربر می شه و همینطور انقضا و … هم اینکه امنیت خوبی داره و …

دلیلی خاصی داره در مقابل ساخت توکن مقاومت می کنید :sweat_smile: ؟


#11

دردسر کم تر
و این که اولین پروژه جدی ای هست که دارم انجام میدم و همین الآنشم خیلی فشار روم هست!
و نیازی هم برای توکن احساس نمیکنم
این پروژه قراره فقط یه سایت باشه نه چیز بیشتر(اپ موبایل و …) و همین session auth کاملا جوابگو هست


#12

سلام
وقتی که اطلاعات کاربر در توکن ذخیره بشه به صورت jwt، سوالی که برا پیش اومده اینکه که اگه بخوایم باز از طریق درخواست به بک اند این بررسی رو انجام بدیم باز همون مشکل هست و اگر بخوایم تو همون فرانت اند این بررسی رو انجام بدیم اونموقع secret key از کجا باید به دست بیاریم از بک اند باشه باز همچنان این مشکل هست اگه تو فرانت اند ذخیره کنیم این از نظر امنیت مشکلی نداره؟


#13

این کد رو هم امتحان کن. من امتحانش نکردم امیدوارم که جواب بده

this.state {
   isLoading: true
}
componentWillMount() {
this.setState({isLoading: true)};
axios.get('/profile/')
  .then(resp => {
    console.log('true', resp);
    this.setState({isLoading:false,isLoggedIn: true});
  })
  .catch(err => {
    console.log('false', err);
    this.setState({isLoading:false,isLoggedIn: false});
  });
 }


render() {
    const isLoggedIn = this.state.isLoggedIn;
    if (this.state.isLoading) {
        return null;//یا یک اسپینر
        }

    if (isLoggedIn) {
      return <Home />
    } else {
    return (
      <form onSubmit={this.handleSubmit}>
        <input type="text" onChange={this.handleUsernameChange} placeholder="username" />
        <input type="password" onChange={this.handlePasswordChange} placeholder="password" />
        <input type="submit" value="Submit" />
      </form>
    );
    }
  }
}

#14

سلام
اینجا در مورد سوالتون بحث شده


#15

میشه شما با یک زبان دیگه توضیح بدید من چیزی از اون موضوع دستگیرم نشد


#16

فرونت نباید پردازش کند . بهتر از بکندی در این وسط باشد که این کار هارو مدیریت کنه