此方案为在钉钉微应用中通过钉钉免登操作实现登录,如果有自己的登录方案,则可以进行适当改进;框架使用的是umi,react-router也适用
1. 场景
日常开发中,经常会遇到这种情况:某个页面是从别的链接直接跳转的,未经登录页面的登录操作;这个时候就需要跳转至登录页进行登录获取用户信息,然后再跳转到之前的页面继续进行操作。
2. 实现思路
3. 实现方案
1. 跳转登录前的页面配置
这里是在最外层的 layout.jsx 组件中监听保存在 dva 中的用户信息/token信息,如果为空,则重定向至 '/' 目录下(如果有登录页,可以重定向至登录页):
// BaseLayout.tsx
/**
* 监听用户信息,为空时,重新进行免登操作,用于点击通知直接进入审批页面
* 为路由添加 from 参数,以便于在登录后能再次进入登录前的页面
*/
useEffect(() => {
if (JSON.stringify(common.userData) === '{}') {
history.replace({
pathname: '/',
query,
state: {
from: pathname, // 关键点:携带当前页面路径信息
},
});
}
}, [common.userData]);
2. 登录页面配置
在 '/' 路径下,进入 pages/index.jsx 会执行 login 动作,执行钉钉的免登操作,这样就会在登录之后,跳转至登录前的页面:
// index.tsx
...
const [loggingIn, setLoggingIn] = useState(true);
const [redirectInfo, setRedirectInfo] = useState({
pathname: '/business-approve',
query: {},
});
useEffect(() => {
// 免登操作:获取用户信息,token信息
ready(() => {
// 获取免登授权码
runtime.permission.requestAuthCode({
corpId:
process.env.NODE_ENV === 'production'
? 'ding10a015c6f52fb517a39a90f97fcb1e09'
: 'ding10a015c6f52fb517a39a90f97fcb1e09', // 企业id
onSuccess({ code }) {
// 获取用户信息
getUserInfoAndToken({ code }).then(res => {
const { code, data } = res;
if (`${code}` === '200' && data) {
const {
userInfo: { userId },
} = data;
// 关键点:如果 location 包含 state 则为登录后需要重定向,设置重定向信息,使用 Redirect 重定向
if (location?.state) {
const { query, state } = location?.state || {};
setRedirectInfo({
pathname: state?.from ?? '/business-approve',
query,
});
}
setLoggingIn(false);
}
});
},
});
});
}, [location]);
...
return loggingIn ? null : <Redirect to={{ ...redirectInfo }} />;