使用auth来知道用户已登录

我的问题是这样的:

我有一个用 react 构建的整个站点,我通过 Nodejs 连接到该站点,我基本上从服务器端获取站点的所有信息。

对于聊天,不可能使用服务器端,因为您需要称为侦听器的东西,对于侦听器,您还需要在 React 中配置 firebase 并且侦听器将起作用,对于聊天,您需要允许连接的用户发送消息,不会对所有人开放。要知道谁已连接,您需要使用名为 auth 的选项。

我需要身份验证,对于 firebase 中的规则,我只能允许连接的用户访问聊天,而不是让规则对所有人开放。

当我将 firebase 中的规则设置为 true 时,聊天有效,但我希望只有注册用户才能使用聊天,我制定了规则。

我收到以下错误:

Uncaught Error in snapshot listener: FirebaseError: Missing or insufficient permissions.

问题是我已经通过服务器端连接,但也需要通过 react 连接,我还需要通过 react 连接以查看谁已连接,并且仅对于已连接的人我希望允许聊天用过的。需要通过反应连接,因为只有通过反应我才能获得 firebase 必须提供的所有功能。只有当您通过 react 直接连接到 firebase 时才能获得 auth,但它要求在 react 中我也将连接聊天。(需要监听器,因为这样用户可以立即收到某人发送给他的消息,并且需要 auth 才能只允许注册用户访问聊天)

为此,我需要通过 react 进行连接,并使用称为 auth 的东西来查看谁已连接。但是整个站点本身是围绕通过 nodejs 登录而构建的,并且在 nodejs 中无法使用 auth。nodejs 无法跟踪 auth,nodejs 最后只以 JSON 形式返回信息。

我不知道如何在react中启用与auth的连接,因为我说的,将所有连接转移到react,会拖动填充站点上的更改,但是通过nodejs登录不允许使用auth,因为它是服务器端,所以我的服务器端只返回 JSON 数据,而不返回其他功能,比如 auth。

我正在考虑通过 react 和 nodejs 进行登录时间,但是我担心它不会起作用,因为它可能会创建 2 个不同的令牌,并且只允许其中一个起作用。

我曾尝试做其他解决方案,如 privateRoute,但它仍然无济于事,因为必须以某种方式获得身份验证,这允许知道谁连接。如果有人可以帮助我或为我提供解决方案,我会很高兴,我认为应该可以用它来解决问题并解决问题。

如何告诉 Firebase 注册用户想要访问聊天?

到目前为止我所做的代码:

通过 nodejs 登录


app.post('/login', login);


exports.login = (req, res) => {
  const user = {
    email: req.body.email,
    password: req.body.password,
  };

  const { valid, errors } = validateLoginData(user);

  if (!valid) return res.status(400).json(errors);

  firebase
    .auth()
    .signInWithEmailAndPassword(user.email, user.password)
    .then((data) => {
      console.log(JSON.stringify(data));
      return data.user.getIdToken();
    })
    .then((token) => {
      db.collection('users')
        .where("email", "==", user.email)
        .get()
        .then((data) => {
          data.forEach((doc) => {
            let userHandle = doc.data().handle;
            db.collection("users")
              .doc(userHandle)
              .get()
              .then((doc) => {
                let user = doc.data();
                db.collection('users').doc(userHandle)
                  .set(user)
                  .then(() => {
                    return res.json({ token: token});
                  })
                  .catch((err) => {
                    console.error(err);
                    return res.status(500).json({ error: err.code });
                  });

              }).catch((error) => {
                console.error(error);
              });


          });
        })
        .catch((err) => {
          console.error(err);
          res.status(500).json({ error: err.code });
        });
    })
    .catch((err) => {
      console.error(err);
      return res
        .status(403)
        .json({ general: "Wrong credentials, please try again" });
    });
};

使用nodejs登录功能

export const loginUser = (userData, history) => (dispatch) => {
//userData contains mail and password  
axios
    .post('/login', userData)
    .then((res) => {
      setAuthorizationHeader(res.data.token);
      //maybe add the auth here somehow
      dispatch(getUserData());
      dispatch
        ({
          type: LOGIN_USER,
          payload: res.data.handle
        });

      history.push('/');
    })
    .catch((err) => {
      dispatch({
        type: SET_ERRORS,
        payload: err.response.data
      });
    });
};

PrivateRoute反应

import React from 'react';
import { Route, Redirect } from 'react-router-dom';


const PrivateRoute = ({component: Component, ...rest}) => {
  return(
    <Route {...rest} component={(props) => {
        const user = localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')) : null;

        if(user){
            return <Component {...props} />
        }else{
            return <Redirect to={`/login`} />
        }

    }} />
   )

 }

export default PrivateRoute

对连接做出反应的身份验证,但不是聊天,聊天我不知道该怎么做

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import './App.css';
import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider';
import createMuiTheme from '@material-ui/core/styles/createMuiTheme';
import jwtDecode from 'jwt-decode';
// Redux
import { Provider } from 'react-redux';
import store from './redux/store';
import { SET_AUTHENTICATED } from './redux/types';
import { logoutUser, getUserData } from './redux/actions/userActions';
// Components
import Navbar from './components/layout/Navbar';
import themeObject from './util/theme';
import AuthRoute from './util/AuthRoute';
import PrivateRoute from './util/PrivateRoute';

// Pages
import home from './pages/home';
import login from './pages/login';
import signup from './pages/signup';
import chat from './pages/chat';

import axios from 'axios';

const theme = createMuiTheme(themeObject);
axios.defaults.baseURL =
  'https://europe-west1-projectdemourl-b123c.cloudfunctions.net/api';

const token = localStorage.FBIdToken;
if (token) {
  const decodedToken = jwtDecode(token);
  if (decodedToken.exp * 1000 < Date.now()) {
    store.dispatch(logoutUser());
    window.location.href = '/login';
  } else {
    store.dispatch({ type: SET_AUTHENTICATED });
    axios.defaults.headers.common['Authorization'] = token;
    store.dispatch(getUserData());
  }
}

class App extends Component {
  render() {
    return (
      <MuiThemeProvider theme={theme}>
        <Provider store={store}>
          <Router>
            <Navbar />
            <div className="container">
              <Switch>
                <Route exact path="/" component={home} />
                <AuthRoute exact path="/login" component={login} />
                <AuthRoute exact path="/signup" component={signup} />
                <PrivateRoute path="/chat" exact component={chat} />
              </Switch>
            </div>
          </Router>
        </Provider>
      </MuiThemeProvider>
    );
  }
}

export default App;

登录 Firebase,客户端

import firebase from "firebase/app";
import "firebase/firestore";

const firebaseConfig = {
    apiKey: process.env.REACT_APP_FIREBASE_KEY,
    authDomain: process.env.REACT_APP_FIREBASE_DOMAIN,
    projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
    storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
    messagingSenderId: process.env.REACT_APP_FIREBASE_SENDER_ID,
    appId: process.env.REACT_APP_FIREBASE_APP_ID,
    measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID
};

firebase.initializeApp(firebaseConfig);
export default firebase;

我用于聊天的功能,在这些功能中我使用了 firebase


export const getRealtimeUsers = (handle) => {

    return async (dispatch) => {
        const db = firebase.firestore();
        const unsubscribe = db.collection("users")
            .onSnapshot((querySnapshot) => {
                db.collection('friends')
                    .get()
                    .then((data) => {
                        let friends = [];
                        data.forEach((doc) => {
                            if (doc.data().isFriends) {
                                if (doc.data().userHandleReceive == handle) {
                                    friends.push(doc.data().userHandleSend);
                                }
                                else {
                                    friends.push(doc.data().userHandleReceive);
                                }
                            }
                        });
                        const users = [];
                        querySnapshot.forEach(function (doc) {
                            if (doc.data().handle != handle && (friends.indexOf(doc.data().handle) > -1) ) {
                                users.push(doc.data());
                            }
                        });
                    })
                    .catch((err) => {
                        console.error(err);
                    });
            });
        return unsubscribe;
    }
}

export const updateMessage = (msgObj) => {

    return async dispatch => {

        const db = firebase.firestore();
        db.collection('conversations')
            .add({
                ...msgObj,
                isView: false,
                createdAt: new Date()
            })
            .then((data) => {
                console.log(data);
            })
            .catch((error) => {
                console.error(error);
            });

    }
}



export const getRealtimeConversations = (user) => {
    return async dispatch => {

        const db = firebase.firestore();
        db.collection('conversations')
            .where('user_uid_1', 'in', [user.uid_1, user.uid_2])
            .orderBy('createdAt', 'asc')
            .onSnapshot((querySnapshot) => {

                const conversations = [];

                querySnapshot.forEach(doc => {
                    if (
                        (doc.data().user_uid_1 == user.uid_1 && doc.data().user_uid_2 == user.uid_2)
                        ||
                        (doc.data().user_uid_1 == user.uid_2 && doc.data().user_uid_2 == user.uid_1)
                    ) {
                        conversations.push(doc.data())
                    }

                });

                dispatch({
                    type: userConstants.GET_REALTIME_MESSAGES,
                    payload: { conversations }
                })
            })
    }
}

这是代码的主要部分,另一个注意事项我需要将反应选项中的loginUser 函数添加到 auth

我想澄清一下,我创建了一个通过 Nodejs 进行身份验证的用户,但 React 没有看到它经过身份验证。

我只是在这里遗漏了一些东西,问题很小,但我不知道它在哪里,以及如何解决它

以上是使用auth来知道用户已登录的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>