OAuth2Callback.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import React, { useContext, useEffect } from 'react';
  2. import { useNavigate, useSearchParams } from 'react-router-dom';
  3. import { useTranslation } from 'react-i18next';
  4. import { API, showError, showSuccess, updateAPI, setUserData } from '../../helpers';
  5. import { UserContext } from '../../context/User';
  6. import Loading from '../common/Loading';
  7. const OAuth2Callback = (props) => {
  8. const { t } = useTranslation();
  9. const [searchParams] = useSearchParams();
  10. const [, userDispatch] = useContext(UserContext);
  11. const navigate = useNavigate();
  12. // 最大重试次数
  13. const MAX_RETRIES = 3;
  14. const sendCode = async (code, state, retry = 0) => {
  15. try {
  16. const { data: resData } = await API.get(
  17. `/api/oauth/${props.type}?code=${code}&state=${state}`,
  18. );
  19. const { success, message, data } = resData;
  20. if (!success) {
  21. throw new Error(message || 'OAuth2 callback error');
  22. }
  23. if (message === 'bind') {
  24. showSuccess(t('绑定成功!'));
  25. navigate('/console/personal');
  26. } else {
  27. userDispatch({ type: 'login', payload: data });
  28. localStorage.setItem('user', JSON.stringify(data));
  29. setUserData(data);
  30. updateAPI();
  31. showSuccess(t('登录成功!'));
  32. navigate('/console/token');
  33. }
  34. } catch (error) {
  35. if (retry < MAX_RETRIES) {
  36. // 递增的退避等待
  37. await new Promise((resolve) => setTimeout(resolve, (retry + 1) * 2000));
  38. return sendCode(code, state, retry + 1);
  39. }
  40. // 重试次数耗尽,提示错误并返回设置页面
  41. showError(error.message || t('授权失败'));
  42. navigate('/console/personal');
  43. }
  44. };
  45. useEffect(() => {
  46. const code = searchParams.get('code');
  47. const state = searchParams.get('state');
  48. // 参数缺失直接返回
  49. if (!code) {
  50. showError(t('未获取到授权码'));
  51. navigate('/console/personal');
  52. return;
  53. }
  54. sendCode(code, state);
  55. }, []);
  56. return <Loading />;
  57. };
  58. export default OAuth2Callback;