Reactjs 未经处理的拒绝(ClientAuthError):需要用户登录。对于静默调用,请求必须包含sid或登录提示
我正在React中创建一个应用程序,并使用“React aad msal”库(),该库使用AzureAD进行身份验证和授权,然后从API(如所示)接收数据(列表任务) 我举了这个例子)。我有以下组件:authProvider.js、TodoConstants.js、TodoActions.js、TodoReducer.js、TodoContainer.js、TodoSaga.js。当我添加const token=wait authProvider.getAccessToken()以从TodoSaga.js中的API请求数据时,我开始收到一个错误:未处理的拒绝(ClientAuthError):需要用户登录。对于静默调用,请求必须包含sid或登录提示。如果添加登录提示:myMail@domain.com“在authenticationParameters中设置authProvider.js,然后它开始正常工作,并提供直接进入身份验证阶段,但如何正确指定loginHint或sid尚不清楚。请告诉我在这种情况下如何正确获取loginHint或sid?哪个参数更可取 authProvider.jsReactjs 未经处理的拒绝(ClientAuthError):需要用户登录。对于静默调用,请求必须包含sid或登录提示,reactjs,react-aad-msal,Reactjs,React Aad Msal,我正在React中创建一个应用程序,并使用“React aad msal”库(),该库使用AzureAD进行身份验证和授权,然后从API(如所示)接收数据(列表任务) 我举了这个例子)。我有以下组件:authProvider.js、TodoConstants.js、TodoActions.js、TodoReducer.js、TodoContainer.js、TodoSaga.js。当我添加const token=wait authProvider.getAccessToken()以从TodoSa
import { MsalAuthProvider, LoginType } from "react-aad-msal";
import { Logger, LogLevel } from "msal";
const config = {
auth: {
clientId: "xxxx-xxxx-xxxx-xxxx",
authority:
"https://login.microsoftonline.com/yyyy-yyyy-yyyy-yyyy",
validateAuthority: true,
redirectUri: "http://localhost:3000",
postLogoutRedirectUri: "http://localhost:3000",
navigateToLoginRequestUrl: true,
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true,
},
};
const authenticationParameters = {
scopes: [
"openid",
"profile",
"api://iiii-iiii-iiii-iiii/access_as_user",
],
// loginHint: loginHint, <---- How to get it correctly?
// sid: sid, <---- How to get it correctly?
};
const options = {
loginType: LoginType.Popup,
tokenRefreshUri: window.location.origin + "/auth.html",
};
export const authProvider = new MsalAuthProvider(
config,
authenticationParameters,
options
);
TodoActions.js
import * as types from "./TodoConstants";
export const fetchTodoDataSourceRequest = () => {
return {
type: types.TODODATASOURCE_API_CALL_REQUEST
};
};
export const fetchTodoDataSourceSuccess = response => {
return {
type: types.TODODATASOURCE_API_CALL_SUCCESS,
data: response,
};
};
export const fetchTodoDataSourceFail = () => {
return {
type: types.TODODATASOURCE_API_CALL_FAILURE
};
};
TodoReducer.js
import * as types from "./TodoConstants";
const initialState = {
fetching: false,
data: null,
error: null,
};
export default function reducer(state = initialState, action) {
switch (action.type) {
case types.TODODATASOURCE_API_CALL_REQUEST:
return { ...state, fetching: true, error: null };
case types.TODODATASOURCE_API_CALL_SUCCESS:
return {
...state,
fetching: false,
data: action.data,
};
case types.TODODATASOURCE_API_CALL_FAILURE:
return {
...state,
fetching: false,
data: null,
error: action.error
};
default:
return state;
}
}
TodoContainer.js
import React from "react";
import TodoView from "../../views/TodoView";
import { connect } from "react-redux";
import * as actions from "./TodoActions";
// import { bindActionCreators } from "redux";
import { bindActionCreators } from "redux";
class TodoDataSourceContainer extends React.PureComponent {
componentDidMount() {
this.props.fetchTodoDataSourceRequest();
}
render() {
return (
<React.Fragment>
<TodoDataSourceView {...this.props} />
</React.Fragment>
);
}
}
const mapStateToProps = ({
TodoDataSourceContainerReducerState: { fetching, data, error},
}) => {
return {
fetching: fetching,
data: data,
error: error,
};
};
const mapDispatchToProps = (dispatch) => {
const {
fetchTodoDataSourceRequest: fetchTodoDataSourceRequest,
} = bindActionCreators(actions, dispatch);
return {
fetchTodoDataSourceRequest: fetchTodoDataSourceRequest,
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(TodoDataSourceContainer);
从“React”导入React;
从“../../views/TodoView”导入TodoView;
从“react redux”导入{connect};
从“/TodoActions”导入*作为操作;
//从“redux”导入{bindActionCreators};
从“redux”导入{bindActionCreators};
类TodoDataSourceContainer扩展了React.PureComponent{
componentDidMount(){
this.props.fetchToDatasourcereQuest();
}
render(){
返回(
);
}
}
常量MapStateTops=({
ToDoDatasourceContainerReduceState:{正在提取,数据,错误},
}) => {
返回{
抓取:抓取,
数据:数据,
错误:错误,
};
};
const mapDispatchToProps=(调度)=>{
常数{
FetchToDatasourcerequest:FetchToDatasourcerequest,
}=bindActionCreators(操作、调度);
返回{
FetchToDatasourcerequest:FetchToDatasourcerequest,
};
};
导出默认连接(
MapStateTops,
mapDispatchToProps
)(TodoDataSourceContainer);
TodoSaga.js
import { takeLatest, call, put } from "redux-saga/effects";
import * as types from "./TodoConstants";
import * as actions from "./TodoActions";
import { authProvider } from "../../../utils/Auth/authProvider";
const request = async (url) => {
const token = await authProvider.getAccessToken(); // <---- After adding this, an error appears and the need for loginHint or sid
const response = await fetch(url, {
method: "GET",
headers: {
Authorization: "Bearer " + token.accessToken,
"Content-Type": "application/json",
},
});
if (response.ok) {
let result = await response.json();
return result;
} else {
alert("Error HTTP: " + response.status);
}
};
export default function* watcherSaga() {
yield takeLatest(types.TODODATASOURCE_API_CALL_REQUEST, workerSaga);
}
function* workerSaga() {
try {
const response = yield request("https://localhost:44351/api/todolist");
yield put(actions.fetchTodoDataSourceSuccess(response));
} catch (error) {
yield put(actions.fetchTodoDataSourceFail(error));
}
}
import{takeLatest,call,put}来自“redux saga/effects”;
从“/TodoConstants”导入*作为类型;
从“/TodoActions”导入*作为操作;
从“../../../utils/Auth/authProvider”导入{authProvider}”;
常量请求=异步(url)=>{
const token=wait authProvider.getAccessToken()//
import { takeLatest, call, put } from "redux-saga/effects";
import * as types from "./TodoConstants";
import * as actions from "./TodoActions";
import { authProvider } from "../../../utils/Auth/authProvider";
const request = async (url) => {
const token = await authProvider.getAccessToken(); // <---- After adding this, an error appears and the need for loginHint or sid
const response = await fetch(url, {
method: "GET",
headers: {
Authorization: "Bearer " + token.accessToken,
"Content-Type": "application/json",
},
});
if (response.ok) {
let result = await response.json();
return result;
} else {
alert("Error HTTP: " + response.status);
}
};
export default function* watcherSaga() {
yield takeLatest(types.TODODATASOURCE_API_CALL_REQUEST, workerSaga);
}
function* workerSaga() {
try {
const response = yield request("https://localhost:44351/api/todolist");
yield put(actions.fetchTodoDataSourceSuccess(response));
} catch (error) {
yield put(actions.fetchTodoDataSourceFail(error));
}
}