首页 > 解决方案 > 查看用户是否已登录

问题描述

我正在使用一些继承的代码,并且对 JWT 身份验证的工作原理没有完全了解,所以请多多包涵。

我有一个登录页面,用户在其中输入密码以查看受保护的内容。然后它指向另一个页面。那部分很好。

我现在想做的是,如果他们输入了密码,就可以在其他页面上显示内容。我尝试检查令牌并将其显示在登录重定向的 console.log 中,但是当我查看其他页面时它没有显示。我知道它在那里,因为我可以在我的 cookie 设置中看到它。

那么......我如何检查它以便我可以有条件地在其他页面上显示内容?提前致谢。

    const jwt = require('jsonwebtoken');
    const exjwt = require('express-jwt');

    module.exports = {
      // INstantiating the express-jwt middleware
      loginPost: function(req, res) {
        const jwtMW = exjwt({
          secret: 'keyboard cat 4 ever'
        });
        let users = [
          {
              id: 1,
              username: 'test1'

          },
          {
              id: 2,
              username: 'test2',
              password: 'asdf12345'
          }
        ];
        const { username, password } = req.body;
        // console.log("user" , username);
        // Use your DB ORM logic here to find user and compare password

        // Finds first username and password match in users array (assumes usernames are unique)
        var user = users.find(u => username == u.username );
        if (user) { // User credentials matched (are valid)
            let token = jwt.sign({ id: user.id, username: user.username }, 'keyboard cat 4 ever', { expiresIn: 129600 }); // Sigining the token
            res.json({
                sucess: true,
                err: null,
                token
            });
        } else { // User credentials did not match (are not valid) or no user with this username/password exists
            res.status(401).json({
                sucess: false,
                token: null,
                err: 'Username or password is incorrect'
            });
        }
      }
    };

    class Login extends Component {
        constructor() {
            super();
            this.handleChange = this.handleChange.bind(this);
            this.handleFormSubmit = this.handleFormSubmit.bind(this);
            this.decode = this.decode.bind(this);
            this.Auth = new AuthService();
        }
        render() {
            // console.log('this login', this);

            return (
                <Fragment>
                    <Grid textAlign='center' style={{ height: '475px', marginBottom: '300px' }} verticalAlign='middle'>
                        <Grid.Column style={{ maxWidth: 450}}>
                            <Header as='h3' textAlign='center' style={{ marginBottom: '30px', marginTop: '190px'}}>
                                {/* <Image src='/logo.png' />  */}
                                Please enter the password to view this content.
                            </Header>
                            <Form size='large' onSubmit={this.handleFormSubmit}>
                                <Segment raised>
                                    <Form.Input fluid icon='lock' type='password' name="username" iconPosition='left' placeholder='password' onChange={this.handleChange} />
                                    {/* <Form.Input
                                        fluid
                                        name="password"
                                        icon='lock'
                                        iconPosition='left'
                                        placeholder='Password'
                                        type='password'
                                        onChange={this.handleChange}
                                    /> */}

                                    <Button className="seeAllWinesBtn" size='small'>
                                        <p className="seeAllWinesText" fluid size='large'>
                                            Login
                                </p></Button>
                                </Segment>
                            </Form>
                            <Header as='h5' textAlign='center' style={{ marginTop: '50px', marginBottom: '100px'}}>
                                This section is for clients only. To gain access, contact your sales rep or the order desk at orders@winewise.biz.
                            </Header>
                            <Link to='/'>
                            <Button> Back to Home
                                </Button>
                                </Link>
                        </Grid.Column>
                    </Grid>
                </Fragment>
            );
        }

        handleChange(e) {
            this.setState(
                {
                    [e.target.name]: e.target.value
                }
            )
            // console.log(this);
        }

        handleFormSubmit(e) {
            e.preventDefault();

            this.Auth.login(this.state.username,this.state.password)
                .then(res =>{

                    // console.log('referrer', document.referrer);
                    // const redirRoute = document.referrer.split('://')[1].split('/');
                    // console.log("route:" , redirRoute);
                    const newLocation = sessionStorage.getItem('referrer');
                    sessionStorage.removeItem('referrer');
                this.props.history.replace(newLocation);
                //window.history.back();

                })
                .catch(err => {
                    alert(err);
                })
        }

        decode(e) {
            e.preventDefault();
            this.Auth.loggedIn()
        }
    }

    export default Login;

import decode from 'jwt-decode';
export default class AuthService {
    // Initializing important variables
    constructor() {
        this.fetch = this.fetch.bind(this) // React binding stuff
        this.login = this.login.bind(this)
        this.getProfile = this.getProfile.bind(this)
    }

    login(username, password) {
        // Get a token from api server using the fetch api
        // console.log('logindomain', this.domain);
        return this.fetch(`/api/login`, {
            method: 'POST',
            body: JSON.stringify({
                username,
                password
            })
        }).then(res => {
            this.setToken(res.token) // Setting the token in localStorage
            return Promise.resolve(res);
        })
    }

    loggedIn() {
        // Checks if there is a saved token and it's still valid
        const token = this.getToken() // GEtting token from localstorage
        // console.log('token', token);
        const loggedIn = !!token && !this.isTokenExpired(token);
        !loggedIn && !sessionStorage.getItem('referrer') && sessionStorage.setItem('referrer', window.location.pathname);
        return loggedIn; // handwaiving here
    }

    isTokenExpired(token) {
        try {
            const decoded = decode(token);
            // console.log("decoded", decoded);
            if (decoded.exp < Date.now() / 1000) { // Checking if token is expired. N
                return true;
            }
            else
                return false;
        }
        catch (err) {
            return false;
        }
    }

    setToken(idToken) {
        // Saves user token to localStorage
        localStorage.setItem('id_token', idToken)
    }

    getToken() {
        // Retrieves the user token from localStorage
        return localStorage.getItem('id_token')
    }

    logout() {
        // Clear user token and profile data from localStorage
        localStorage.removeItem('id_token');
    }

    getProfile() {
        // Using jwt-decode npm package to decode the token
        return decode(this.getToken());
    }


    fetch(url, options) {
        // performs api calls sending the required authentication headers
        const headers = {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        }

        // Setting Authorization header
        // Authorization: Bearer xxxxxxx.xxxxxxxx.xxxxxx
        if (this.loggedIn()) {
            headers['Authorization'] = 'Bearer ' + this.getToken()
        }

        return fetch(url, {
            headers,
            ...options
        })
            .then(this._checkStatus)
            .then(response => response.json())
    }

    _checkStatus(response) {
        // raises an error in case response status is not a success
        if (response.status >= 200 && response.status < 300) { // Success status lies between 200 to 300
            return response
        } else {
            var error = new Error(response.statusText)
            error.response = response
            throw error
        }
    }
}

标签: reactjsauthenticationjwt

解决方案


正如您在评论中提到的,最常见的解决方案之一是将令牌存储在浏览器的 localStorage 中,然后您可以使用localStorage.getItem(item-name). 但是,您必须使用您的服务器验证该令牌,以确保它没有过期并且是一个有效的令牌,因此您需要在您的后端提供某种服务来接受令牌,验证它并返回其状态,以便您可以在前端做出有关渲染/访问的决定。


推荐阅读