草庐IT

全局路由守卫-登录鉴权

sweetBoy_9126 2023-09-29 原文
const router = createRouter({
  history,
  routes,
})
router.beforeEach(async (to, from) => {
  if (to.path === '/' || to.path.startsWith('/welcome') || to.path.startsWith('/sign_in')) {
    return true
  } else {
   const path =  await http.get('/me').then(() => true, () => '/sign_in?return_to=' + to.path)
    return true
  }
})

问题1: 上面的代码每次路由跳转的时候都会调用 me 接口
解决方法:如果我们不想每次路由跳转都调用接口我们可以把接口调用写在外面

const promise = http.get('/me')
router.beforeEach(async (to, from) => {
  if (to.path === '/' || to.path.startsWith('/welcome') || to.path.startsWith('/sign_in') || to.path.startsWith('/start')) {
    return true
  } else {
    const path = await promise.then(() => true, () => '/sign_in?return_to=' + to.path)
    return path
  }
})

问题2:上面接口是只调一次了,但是我们登录成功后页面不会跳转
原因:以登录成功后跳转 http://localhost:8082/#/sign_in?return_to=/items/create 为例,我们的 /me 接口依赖 jwt,没登录就没有 jwt,所以一开始我们未登录从 items/create 跳到 sign_in 没问题,但是登录成功后因为我们的 /me 接口只在初始化的时候调用,所以即使我们登录成功这个接口还是走的一开始的 catch 所以还是跳到了登录页
解决方法:在用户登录成功成功后主动去更新

  • me.tsx
import { AxiosResponse } from "axios";
import { http } from "./Http";
export let mePromise: Promise<AxiosResponse<{
  resource: {
    id: number
  }
}>> | undefined

export const refreshMe = () => {
  mePromise = http.get<{ resource: { id: number }}>('/me') 
  return mePromise
}

export const fetchMe = refreshMe
  • signInPage
// 点击登录按钮后
refreshMe()
router.push(returnTo || '/')
  • main.ts
import { mePromise, fetchMe } from './shared/me';

fetchMe()

router.beforeEach(async (to, from) => {
  if (to.path === '/' || to.path.startsWith('/welcome') || to.path.startsWith('/sign_in') || to.path.startsWith('/start')) {
    return true
  } else {
    const path = await mePromise!.then(() => true, () => '/sign_in?return_to=' + to.path)
    return path
  }
})

有关全局路由守卫-登录鉴权的更多相关文章

  1. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  2. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  3. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

    我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

  4. ruby-on-rails - Rails - 从命名路由中提取 HTTP 动词 - 2

    Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba

  5. ruby-on-rails - 如何在 Rails 中设置路由的默认格式? - 2

    路由有如下代码:resources:orders,only:[:create],defaults:{format:'json'}resources:users,only:[:create,:update],defaults:{format:'json'}resources:delivery_types,only:[:index],defaults:{format:'json'}resources:time_corrections,only:[:index],defaults:{format:'json'}是否可以使用1个字符串为所有资源设置默认格式,每行不带“默认值”散列?谢谢。

  6. ruby - 在 RSpec 中 stub /模拟全局常量 - 2

    我有一个gem,它有一个根据Rails.env的不同行为的方法:defself.envifdefined?(Rails)Rails.envelsif...现在我想编写一个规范来测试这个代码路径。目前我是这样做的:Kernel.const_set(:Rails,nil)Rails.should_receive(:env).and_return('production')...没关系,只是感觉很丑。另一种方法是在spec_helper中声明:moduleRails;end而且效果也很好。但也许有更好的方法?理想情况下,这应该有效:rails=double('Rails')rails.sho

  7. ruby - 将全局 $stdout 重新分配给控制台 - ruby - 2

    我正在尝试将$stdout设置为临时写入一个文件,然后返回到一个文件。test.rb:old_stdout=$stdout$stdout.reopen("mytestfile.out",'w+')puts"thisgoesinmytestfile"$stdout=old_stdoutputs"thisshouldbeontheconsole"$stdout.reopen("mytestfile1.out",'w+')puts"thisgoesinmytestfile1:"$stdout=old_stdoutputs"thisshouldbebackontheconsole"这是输出。r

  8. ruby - 在模块/类之间共享全局记录器 - 2

    在许多ruby​​类之间共享记录器实例的最佳(正确)方法是什么?现在我只是将记录器创建为全局$logger=Logger.new变量,但我觉得有更好的方法可以在不使用全局变量的情况下执行此操作。如果我有以下内容:moduleFooclassAclassBclassC...classZend在所有类之间共享记录器实例的最佳方式是什么?我是以某种方式在Foo模块中声明/创建记录器还是只是使用全局$logger没问题? 最佳答案 在模块中添加常量:moduleFooLogger=Logger.newclassAclassBclassC..

  9. ruby - Sinatra 中的全局救援和日志记录异常 - 2

    如何在出现异常时指定全局救援,如果您将Sinatra用于API或应用程序,您将如何处理日志记录? 最佳答案 404可以在not_found方法的帮助下处理,例如:not_founddo'Sitedoesnotexist.'end500s可以通过调用带有block的错误方法来处理,例如:errordo"Applicationerror.Plstrylater."end错误的详细信息可以通过request.env中的sinatra.error访问,如下所示:errordo'Anerroroccured:'+request.env['si

  10. ruby - 为什么允许在 Ruby 类之外定义全局方法? - 2

    我读过这个:Let’sstartwithasimpleRubyprogram.We’llwriteamethodthatreturnsacheery,personalizedgreeting.defsay_goodnight(name)result="Goodnight,"+namereturnresultend我的理解是,方法是定义在类中的函数或子程序,可以关联到类(类方法)或对象(实例方法)。那么,如果它不是在类中定义的,怎么可能是方法呢? 最佳答案 当你在Ruby中以这种方式在全局范围内定义一个函数时,它在技术上变成了Obje

随机推荐