通过 Azure AD OAuth 登录获取用户数据 - React Native Expo App
Getting user data through an Azure AD OAuth login - React Native Expo App
在我的应用程序中,我使用 useAuthRequest 通过 Microsoft Azure AD 登录 对用户进行身份验证,正如 Expo Documentation 所建议的那样(此登录方法成功运行)。在我的请求中,我在范围 ['openid', 'profile', 'email']
.
中解析
我想在我的应用程序中显示用户名和电子邮件等数据,但不知道如何获取这些数据。
经过一些研究,我发现这个数据保存在一个JWT format的Token中,并且可以使用简单的JWT解码器包对其进行解码。
问题是我不知道如何或从哪里获得特定的令牌来对其进行解码。
这是我的代码的摘录:
const discovery = useAutoDiscovery(`${config.ENDPOINT_URL}`);
const [request, response, promptAsync] = useAuthRequest(
{
clientId: `${config.CLIENT_ID}`,
clientSecret: `${config.CLIENT_SECRET}`,
scopes: [ 'openid', 'profile', 'email'],
prompt: 'login',
redirectUri: "msauth.*MyBundleId*://auth",
returnUrl: "msauth.*MyBundleId*://auth",
},
discovery,
console.log(discovery)
);
我认为值得一提的console.log(discovery)
returns两个具体的link:
"token_endpoint": "https://login.microsoftonline.com/*MyAppsTenantId*/oauth2/v2.0/token",
和:
"userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo"
在我的浏览器中输入 token_endpoint 时,显示一条错误消息
AADSTS900561: The endpoint only accepts POST, OPTIONS requests.
Received a GET request.
并且在我的浏览器上输入 userinfo_endpoint link 时,它 returns 一个包含以下数据的散列:
{"error":{"code":"InvalidAuthenticationToken","message":"Access token is empty.","innerError":{"date":"2022-04-28T13:00:07","request-id":"*MyAppTenantId","client-request-id":"*ClientRequestId*"}}}
有用link秒:
如果您对如何获取包含用户数据的 JWT 令牌有任何线索、提示或信息,请在下方分享,我将非常乐意阅读和发表评论。
请检查参考文献是否可以解决:
首先错误AADSTS900561可能是因为
- 浏览器上的第 3 方 cookie。为避免这种情况 >打开 cookie 设置 >取消选择
“阻止 third-party cookies”,清除你的 cookies。
- 或者是权限问题url,请检查是否是
正确。
- 根据Microsoft docs :The error AADSTS900561
To redeem the code for an access token, the app should send a POST request to the /token endpoint. Also, prior to this, you should provide an authorization code and send it in the POST request to the /token endpoint.
关于获取token和解码,找不到参考文献,请检查他们是否可以帮助或提供继续进行的线索。
取自 React Native on Expo- Stack Overflow reference
const discovery = useAutoDiscovery('https://login.microsoftonline.com/TENANT_ID/v2.0');
// Request
const [request, response, promptAsync] = useAuthRequest(
{
clientId: 'YOUR - CLIENT - ID',
scopes: ['openid', 'profile', 'email', 'offline_access' 'user.read
],
redirectUri: makeRedirectUri({
scheme: 'exp://YOUR IP ADDRESS:19000'
}),
grant_type: ‘authorization_code’,
// codeChallenge: 'CODE_CHALLENGE',
// codeChallengeMethod: 'S256',
// usePKCE: true
},
discovery
);
React.useEffect(() => {
if (response && 'params' in response) {
if (response.params && 'code' in response.params) {
(async function getToken() {
console.log('-----------------------')
console.log(response.params.code)
console.log('-----------------------')
try {
// @ts-ignore
const { accessToken } = await exchangeCodeAsync({
code: response.params.code,
clientId: 'CLIENT - ID',
redirectUri: makeRedirectUri({
scheme: ' '
}),
scopes: ['openid', 'profile', 'email', 'offline_access'],
grant_type: "authorization_code",
extraParams: {
// code_verifier: "CODE_VERIFIER",
code_verifier: request?.codeVerifier || '' ,
},
}, {
tokenEndpoint: 'https://login.microsoftonline.com/TENNANT_ID/oauth2/v2.0/token' //
})
console.log(accessToken)
请检查每个参考资料:
- expo-react-native-azure-ad-2| GitHub
- 同时勾选
- 看看这个 github discussion on expo issues 是否可以提供获取用户令牌的想法。
解码:
decodeJwtToken(token) {
console.log("Entered decodeJwtToken function")
var temp = token.replace(/-/i, "+");
var newtoken = temp.replace(/_/i, "/");
var parsedObj = JSON.parse(new Buffer(newtoken.split(".")[1], "base64").toString())
console.log(parsedObj) }
检查是否可以从令牌中提取用户以进行解析>JSON.stringify(user)。
参见 Decoding JWT token - SO
&npm:expo-react-native-azure-ad-2 | Skypack
如果其他声明需要,您可以在应用程序令牌配置中配置可选声明:
以防万一如果使用react native azure auth,下面的代码可以提供用户信息:
try {
let tokens = await azureAuth.webAuth.authorize({scope: 'openid profile User.Read Mail.Read' })
this.setState({ accessToken: tokens.accessToken });
let info = await azureAuth.auth.msGraphRequest({token: tokens.accessToken, path: '/me'})
this.setState({ user: info.displayName, userId: tokens.userId })
} catch (error) {
console.log(error)
}
我终于解决了这个问题!
我找到了一个名为 azure-ad-graph-expo 的库,它以非常简单的方式完成了我想做的事情 -> 不需要 API 调用和解析访问令牌。
这是我的代码的摘录:
const [resultData, setResultData] = useState({});
const _handlePressAsync = async () => {
let result = await openAuthSession(azureAdAppProps);
setResultData({ result });
}
const azureAdAppProps = {
clientId : `******************`,
tenantId : `******************`,
scope : 'user.read',
redirectUrl : AuthSession.makeRedirectUri({ path: "auth"}),
returnUrl : "mybundleid://auth",
clientSecret : `******************`,
domainHint : 'login.microsoftonline.com',
prompt : 'login'
};
您必须在 Azure 门户中设置重定向 Url。
此代码成功运行,因为它是在应用构建本身而不是 Expo Go 应用中测试的:
=> 要创建构建,运行 expo build:ios
或 expo build:android
=> 如果您想在 Expo Go 应用程序中对其进行测试,请在 Azure AD 门户上将您的本地主机设置为重定向Url,并将代码设置为redirectUrl: AuthSession.makeRedirectUri()
=> 对于 bundle id,您可以设置自己的 -> 在 app.json 内创建 "scheme"
在 "expo:"
括号内。捆绑 ID 按以下模式编写:com.your-company.app-name
.
为了测试我的应用程序是否正在获取用户数据,在登录按钮下方添加了以下代码:
{resultData ? (
<Text>{JSON.stringify(resultData)}</Text>
) :
<Text>Nothing to see here.</Text>}
这是验证后的结果:
User Data
如果您对此问题有任何疑问或补充,请随时在下方发表评论! :D
非常感谢此线程中的所有帮助和评论!
在我的应用程序中,我使用 useAuthRequest 通过 Microsoft Azure AD 登录 对用户进行身份验证,正如 Expo Documentation 所建议的那样(此登录方法成功运行)。在我的请求中,我在范围 ['openid', 'profile', 'email']
.
我想在我的应用程序中显示用户名和电子邮件等数据,但不知道如何获取这些数据。
经过一些研究,我发现这个数据保存在一个JWT format的Token中,并且可以使用简单的JWT解码器包对其进行解码。
问题是我不知道如何或从哪里获得特定的令牌来对其进行解码。
这是我的代码的摘录:
const discovery = useAutoDiscovery(`${config.ENDPOINT_URL}`);
const [request, response, promptAsync] = useAuthRequest(
{
clientId: `${config.CLIENT_ID}`,
clientSecret: `${config.CLIENT_SECRET}`,
scopes: [ 'openid', 'profile', 'email'],
prompt: 'login',
redirectUri: "msauth.*MyBundleId*://auth",
returnUrl: "msauth.*MyBundleId*://auth",
},
discovery,
console.log(discovery)
);
我认为值得一提的console.log(discovery)
returns两个具体的link:
"token_endpoint": "https://login.microsoftonline.com/*MyAppsTenantId*/oauth2/v2.0/token",
和:
"userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo"
在我的浏览器中输入 token_endpoint 时,显示一条错误消息
AADSTS900561: The endpoint only accepts POST, OPTIONS requests. Received a GET request.
并且在我的浏览器上输入 userinfo_endpoint link 时,它 returns 一个包含以下数据的散列:
{"error":{"code":"InvalidAuthenticationToken","message":"Access token is empty.","innerError":{"date":"2022-04-28T13:00:07","request-id":"*MyAppTenantId","client-request-id":"*ClientRequestId*"}}}
有用link秒:
如果您对如何获取包含用户数据的 JWT 令牌有任何线索、提示或信息,请在下方分享,我将非常乐意阅读和发表评论。
请检查参考文献是否可以解决:
首先错误AADSTS900561可能是因为
- 浏览器上的第 3 方 cookie。为避免这种情况 >打开 cookie 设置 >取消选择 “阻止 third-party cookies”,清除你的 cookies。
- 或者是权限问题url,请检查是否是 正确。
- 根据Microsoft docs :The error AADSTS900561
To redeem the code for an access token, the app should send a POST request to the /token endpoint. Also, prior to this, you should provide an authorization code and send it in the POST request to the /token endpoint.
关于获取token和解码,找不到参考文献,请检查他们是否可以帮助或提供继续进行的线索。
取自 React Native on Expo- Stack Overflow reference
const discovery = useAutoDiscovery('https://login.microsoftonline.com/TENANT_ID/v2.0');
// Request
const [request, response, promptAsync] = useAuthRequest(
{
clientId: 'YOUR - CLIENT - ID',
scopes: ['openid', 'profile', 'email', 'offline_access' 'user.read
],
redirectUri: makeRedirectUri({
scheme: 'exp://YOUR IP ADDRESS:19000'
}),
grant_type: ‘authorization_code’,
// codeChallenge: 'CODE_CHALLENGE',
// codeChallengeMethod: 'S256',
// usePKCE: true
},
discovery
);
React.useEffect(() => {
if (response && 'params' in response) {
if (response.params && 'code' in response.params) {
(async function getToken() {
console.log('-----------------------')
console.log(response.params.code)
console.log('-----------------------')
try {
// @ts-ignore
const { accessToken } = await exchangeCodeAsync({
code: response.params.code,
clientId: 'CLIENT - ID',
redirectUri: makeRedirectUri({
scheme: ' '
}),
scopes: ['openid', 'profile', 'email', 'offline_access'],
grant_type: "authorization_code",
extraParams: {
// code_verifier: "CODE_VERIFIER",
code_verifier: request?.codeVerifier || '' ,
},
}, {
tokenEndpoint: 'https://login.microsoftonline.com/TENNANT_ID/oauth2/v2.0/token' //
})
console.log(accessToken)
请检查每个参考资料:
- expo-react-native-azure-ad-2| GitHub
- 同时勾选
- 看看这个 github discussion on expo issues 是否可以提供获取用户令牌的想法。
解码:
decodeJwtToken(token) {
console.log("Entered decodeJwtToken function")
var temp = token.replace(/-/i, "+");
var newtoken = temp.replace(/_/i, "/");
var parsedObj = JSON.parse(new Buffer(newtoken.split(".")[1], "base64").toString())
console.log(parsedObj) }
检查是否可以从令牌中提取用户以进行解析>JSON.stringify(user)。 参见 Decoding JWT token - SO
&npm:expo-react-native-azure-ad-2 | Skypack
如果其他声明需要,您可以在应用程序令牌配置中配置可选声明:
以防万一如果使用react native azure auth,下面的代码可以提供用户信息:
try {
let tokens = await azureAuth.webAuth.authorize({scope: 'openid profile User.Read Mail.Read' })
this.setState({ accessToken: tokens.accessToken });
let info = await azureAuth.auth.msGraphRequest({token: tokens.accessToken, path: '/me'})
this.setState({ user: info.displayName, userId: tokens.userId })
} catch (error) {
console.log(error)
}
我终于解决了这个问题!
我找到了一个名为 azure-ad-graph-expo 的库,它以非常简单的方式完成了我想做的事情 -> 不需要 API 调用和解析访问令牌。
这是我的代码的摘录:
const [resultData, setResultData] = useState({});
const _handlePressAsync = async () => {
let result = await openAuthSession(azureAdAppProps);
setResultData({ result });
}
const azureAdAppProps = {
clientId : `******************`,
tenantId : `******************`,
scope : 'user.read',
redirectUrl : AuthSession.makeRedirectUri({ path: "auth"}),
returnUrl : "mybundleid://auth",
clientSecret : `******************`,
domainHint : 'login.microsoftonline.com',
prompt : 'login'
};
您必须在 Azure 门户中设置重定向 Url。
此代码成功运行,因为它是在应用构建本身而不是 Expo Go 应用中测试的:
=> 要创建构建,运行
expo build:ios
或expo build:android
=> 如果您想在 Expo Go 应用程序中对其进行测试,请在 Azure AD 门户上将您的本地主机设置为重定向Url,并将代码设置为
redirectUrl: AuthSession.makeRedirectUri()
=> 对于 bundle id,您可以设置自己的 -> 在 app.json 内创建
"scheme"
在"expo:"
括号内。捆绑 ID 按以下模式编写:com.your-company.app-name
.
为了测试我的应用程序是否正在获取用户数据,在登录按钮下方添加了以下代码:
{resultData ? (
<Text>{JSON.stringify(resultData)}</Text>
) :
<Text>Nothing to see here.</Text>}
这是验证后的结果: User Data
如果您对此问题有任何疑问或补充,请随时在下方发表评论! :D 非常感谢此线程中的所有帮助和评论!