【问题标题】:Meteor: Calling verifyEmail From React Client?Meteor:从 React 客户端调用 verifyEmail?
【发布时间】:2020-06-13 12:58:31
【问题描述】:

我已经阅读了很多关于 using Accounts.onEmailVerificationLinkAccounts.verifyEmail 的 SO 帖子,但我还没有找到一个似乎可以解释如何从 React 客户端调用它们的帖子。

我设置了 React Router 以将电子邮件验证链接上的点击路由到名为 ConfirmEmail 的 React 组件。路由器将验证令牌捕获到props.match.params.emailValidationToken

ConfirmEmail 组件如下所示:

import React, {useEffect, useRef, useState} from "react";

function ConfirmEmail(props) {
    const {client, match, history} = props;

    const doSetUp = useRef(true);
    const emailVerificationToken = useRef(props.match.params.emailValidationToken);

    if (doSetUp.current){
        doSetUp.current = false;
        debugger;
        Accounts.onEmailVerificationLink(function(token, done) {
            Accounts.verifyEmail(emailVerificationToken.current, function(error) {
                debugger;
                if (error) {
                    console.log(error)
                } else {
                    console.log(success)
                }
            })
        });
    }


    return (
        <p>Your email address has been verified.</p>
    )
}

export default ConfirmEmail;

我已经尝试了几种不同的方法,但我还没有找到有效的方法。

从 React 客户端处理点击 Meteor 电子邮件验证链接的正确方法是什么?

【问题讨论】:

    标签: reactjs meteor meteor-accounts


    【解决方案1】:

    好的,我不使用 React Hooks,但我想你会发现很容易根据自己的喜好移植它。

    这一切都需要在 componentDidMount() 中发生。这可确保您使用令牌并且您只运行此过程一次。 在以下代码中,toastr 是客户端的 UI 通知系统。

    
    import React, { Component } from 'react'
    import { connect } from 'react-redux' // if you use redux, here it is used to get the user slug from props.
    import { Link } from 'react-router-dom'
    import PropTypes from 'prop-types' // not relevant
    import { Accounts } from 'meteor/accounts-base'
    import { toastr } from 'react-redux-toastr' // not relevant
    import { TiWarningOutline, TiThumbsOk } from '../../components/shared/Icons/icons' // not relevant
    
    class ConfirmEmail extends Component {
      constructor (props) {
        super(props)
        this.state = {
          linkExpired: false,
          logged: true // I need to know if the user is logged in before I test the token
        }
      }
    
      componentDidMount () {
        const { match, history, slug } = this.props
        const token = match.params.token
    
        // If the user is not logged in I cannot test the token against an email.
        if (!slug) {
          this.setState({ logged: false })
          return
        }
    
        Accounts.verifyEmail(token, err => {
          if (err && err.reason === 'Verify email link expired') {
            this.setState({ linkExpired: true })
          }
          // Inform the user what went wrong
          if (err) {
            toastr.light('Could not verify email!', `Error: ${err.reason}`, { timeOut: 2000, icon: (<TiWarningOutline style={{ fontSize: 42, color: 'red' }} />) })
          } else {
            // Confirm to user and move on to where you want to direct the user first or ask the user to close the window...or else
            toastr.light('You\'ve Successfully Confirmed Your Email Address!', { timeOut: 4000, icon: (<TiThumbsOk style={{ fontSize: 42, color: 'rgb(74, 181, 137)' }} />) })
            history.push('/feeds')
          }
        })
      }
    
      render () {
        const { linkExpired, logged } = this.state
        return (
          <div style={{ textAlign: 'center', paddingTop: 80 }}>
            {logged
              ? <>
                {linkExpired
                  ? <p>This link has expired.</p>
                  : <>
                    <img src={`${IMAGE_BANK}/images/6.svg`} style={{ width: 36 }} /> // this is a spinner
                    <p>Awaiting confirmation ...</p>
                  </>}
              </>
              : <>
                <p style={{ maxWidth: 360, margin: '0 auto' }}>
                  In order to verify your email address you need to be authenticated. Please sign in and try the verification link from your email one more time.
                </p>
                <br />
                <Link to='/signin' className='btn btn-primary'>Sign In</Link>
              </>
            }
          </div>
        )
      }
    }
    
    // this block is relevant in Redux context. Just gets the slug (or some other way to check if the user is logged in.)
    const mapStateToProps = state => {
      const currentUser = state.user.currentUser
      return {
        slug: currentUser?.slug
      }
    }
    export default connect(mapStateToProps, { })(ConfirmEmail)
    
    // from here, not so relevant
    ConfirmEmail.propTypes = {
      params: PropTypes.object
    }
    
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      • 2017-05-04
      • 2013-06-26
      • 1970-01-01
      • 1970-01-01
      • 2015-08-18
      • 1970-01-01
      相关资源
      最近更新 更多