I created a Static Web App on Azure using Sveltekit but it seems that SSR is not working when I add AAD authentication with staticwebapp.config.json. Here is an example:
+page.server.js
export function load() {
return {
post: {
title: 'Title',
content: 'Content'
}
};
}
+page.svelte
<script>
export let data;
</script>
<h1>{data.post.title}</h1>
<div>{data.post.content}</div>
If I use +page.js rather than +page.server.js it works perfectly. The AAD auth works also using +page.js and I can see my auth infos at /.auth/me
The page with +page.server.js is not working and redirect me to my home page.
staticwebapp.config.json
{
"auth": {
"identityProviders": {
"azureActiveDirectory": {
"registration": {
"openIdIssuer": "https://login.microsoftonline.com/<my-tenant-id>/v2.0",
"clientIdSettingName": "AAD_CLIENT_ID",
"clientSecretSettingName": "AAD_CLIENT_SECRET"
}
}
}
},
"navigationFallback": {
"rewrite": "index.html",
"exclude": ["/images/*.{png,jpg,gif}", "/css/*"]
},
"routes": [
{
"route": "/login",
"rewrite": "/.auth/login/aad",
"allowedRoles": ["anonymous", "authenticated"]
},
{
"route": "/.auth/login/github",
"statusCode": 404
},
{
"route": "/.auth/login/twitter",
"statusCode": 404
},
{
"route": "/logout",
"redirect": "/.auth/logout",
"allowedRoles": ["anonymous", "authenticated"]
},
{
"route": "/*",
"allowedRoles": ["authenticated"]
}
],
"responseOverrides": {
"401": {
"redirect": "/login",
"statusCode": 302
}
},
"globalHeaders": {
"content-security-policy": "default-src https: 'unsafe-eval' 'unsafe-inline'; object-src 'none'",
"Cache-Control": "no-cache, no-store"
},
"mimeTypes": {
".json": "text/json"
}
}
Thanks in advance for your help.
If I use +page.js rather than +page.server.js it works perfectly. The AAD auth works also using +page.js and I can see my auth infos at /.auth/me
The page with +page.server.js is not working and redirect me to my home page.
Related
I've implemented a really simple Razor Webassembly application and used Azure Active Directory B2C as source of truth for authenticate and authorize user.
When I type the StaticWebApp url in my browser, I'm redirected to the login page as expected and here I type my user name and password. Once the login is successfull, the index page of my app is shown and I can see my email as logged user..
So far so good..
But, then when I click the Logout button, I'm redirected to the login page as expected but I'm not actually logged out because if I visit the page again, I see myself as logged again without performing any further login operation.
This is my staticwebapp.config.json file
{
"responseOverrides":
{
"401":
{
"statusCode": 302,
"redirect": "/.auth/login/aadb2c"
}
},
"routes":[
{
"route": "/.auth/login/aadb2c",
"allowedRoles": [ "anonymous" ]
},
{
"route": "/.auth/login/aad",
"allowedRoles": [ "anonymous", "authenticated" ],
"statusCode": 404
},
{
"route": "/.auth/login/apple",
"allowedRoles": [ "anonymous", "authenticated" ],
"statusCode": 404
},
{
"route": "/.auth/login/facebook",
"allowedRoles": [ "anonymous", "authenticated" ],
"statusCode": 404
},
{
"route": "/.auth/login/github",
"allowedRoles": [ "anonymous", "authenticated" ],
"statusCode": 404
},
{
"route": "/.auth/login/google",
"allowedRoles": [ "anonyous", "authenticated" ],
"statusCode": 404
},
{
"route": "/.auth/login/twitter",
"allowedRoles": [ "anonymous", "authenticated" ],
"statusCode": 404
},
{
"route": "/login*",
"allowedRoles": [ "anonymous" ],
"rewrite": "/.auth/login/aadb2c"
},
{
"route": "/logout*",
"allowedRoles": [ "authenticated" ],
"rewrite": "/.auth/logout"
},
{
"route": "/.auth/me",
"allowedRoles": ["authenticated","anonymous"]
},
],
"auth":
{
"identityProviders":
{
"customOpenIdConnectProviders":
{
"aadb2c":
{
"registration":
{
"clientIdSettingName": "AADB2C_PROVIDER_CLIENT_ID",
"clientCredential":
{
"clientSecretSettingName": "AADB2C_PROVIDER_CLIENT_SECRET"
},
"openIdConnectConfiguration":
{
"wellKnownOpenIdConfiguration": "https://{tenantId}.b2clogin.com/
{tenantId}.onmicrosoft.com/v2.0/.well-known/
openid-configuration?p={userFlowName}"
}
},
"login":
{
"nameClaimType": "emails",
"scopes": ["openid"]
}
}
}
}
}
}
and here is the LoginDisplay razor component which I show in the home page:
<AuthorizeView>
<Authorized>
Hello #context.User?.Identity?.Name!
Log out
</Authorized>
<NotAuthorized>
Log in
</NotAuthorized>
</AuthorizeView>
What am I missing?
EDIT: other info that may be useful.
In the user flow, Require ID Token in logout requests property is set to True
Front-channel logout URL for the registered app is set to 'https://{NAME}.azurestaticapps.net/.auth/logout'
It seems that people just implement login functionality in their application and forget about logout :)
I fixed this issue modifying the route rules. The user must be logged-out from your authentication provider as well.
I'm trying to call the youtube API to make a playlist on my channel from a chrome extension and I keep getting this error code returned back to me;
domain: "youtube.parameter"
location: "parameters."
locationType: "other"
message: "No filter selected. Expected one of: channelId, id, mine"
reason: "missingRequiredParameter"
this is my manifest file:
"action": {
"default_title": "multi monitor for youtube"
},
"oauth2": {
"client_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"scopes": [
"https://www.googleapis.com/auth/youtube.force-ssl",
"https://www.googleapis.com/auth/youtubepartner",
"https://www.googleapis.com/auth/youtube"
]
},
"permissions": [
"identity"
],
"host_permissions": ["https://www.googleapis.com/"],
"background": {
"service_worker": "background.js"
},
"manifest_version": 3
and this is my background file
chrome.action.onClicked.addListener(function(){
chrome.identity.getAuthToken({ interactive: true }, function (token) {
console.log(token);
let fetch_options = {
//method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
"part": [
"snippet,status"
],
"resource": {
"snippet": {
"title": "Sample playlist created via API",
"channelId": "UC0E5pDp_c2riLV4UhEgynKA",
"description": "This is a sample playlist description.",
"tags": [
"sample playlist",
"API call"
],
"defaultLanguage": "en"
},
"status": {
"privacyStatus": "private"
},
}
};
fetch(
'https://www.googleapis.com/youtube/v3/playlists',
fetch_options
)
.then((response) => response.json()) // Transform the data into json
.then(function (data) {
console.log(data);//contains the response of the created event
});
});
});
I tried to use the second answer from this question but there are some changes that had to be made in order to call the youtube API instead of the calendar.
Because I was getting the error I tried adding the channel ID to the snippet and it still doesn't work.
I'm very new to creating chrome extensions so please forgive me if there is an obvious mistake here.
I finally figured it out!
so the first thing that I had to change was I had to add my API key and part=snippet to the fetch URL. Second I looked into the fetch method and I found out that you needed to specify the body of the message with body : JSON.stringify().
so this is the background.js that I ended up with
chrome.identity.getAuthToken({ interactive: true }, function (token) {
console.log(token);
let fetchString = 'https://www.googleapis.com/youtube/v3/playlists?part=snippet&key=<API key>'
let post =
{
"part": [
"kind,snippet,channelTitle,status"
],
"kind": "youtube#playlistItem",
"snippet":{
"title": "Sample playlist created via API",
"channelID": "<channel ID>",
"description": "This is a sample playlist description.",
"tags": [
"sample playlist",
"API call"
],
"defaultLanguage": "en",
"status": {
"privacyStatus": "private"
}
}
}
let fetchOptions = {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(post),
}
fetch(fetchString,fetchOptions)
.then((response) => response.json()) // Transform the data into json
.then(function (data) {
console.log(data);//contains the response of the created event
});
});
I'm using Loopback4 as an Central API. I'm trying to call a method of the 3rd party API through a remote method in Loopback. I'm using Strapi as 3rd party API and communicate this to loopback4
With Loopback, I have a datasource which looks like the following:
const strapiConfig = {
name: 'strapi',
connector: 'rest',
baseURL: appConfig.strapi.host,
crud: false,
options: {
headers: {
"accept": "application/json",
"content-type": "application/json",
"cache-control": "no-cache",
"Authorization" : `Bearer ${appConfig.strapi.token}`
}
},
operations: [
{
"template": {
"method": "GET",
"url": `${strapiUrl}/pages/{pageId}`
},
"functions": {
"getOnePage": ["pageId"]
}
},
{
"template": {
"method": "GET",
"url": `${strapiUrl}/pages`
},
"functions": {
"getPages": ""
}
},
{
"template": {
"method": "GET",
"url": `${strapiUrl}/glossary/{id}`
},
"functions": {
"getOneGlossary": ['id']
}
},
{
"template": {
"method": "GET",
"url": `${strapiUrl}/glossary`
},
"functions": {
"getGlossary": ""
}
},
{
"template": {
"method": "GET",
"url": `${strapiUrl}/faq`
},
"functions": {
"getFaqs": ""
}
},
{
"template": {
"method": "GET",
"url": `${strapiUrl}/faq/{id}`
},
"functions": {
"getOneFaq": ['id']
}
}
]
};
the only endpoint that are working is the pages
Any advice is welcome. Thanks!
What kind of error/status code do you get when calling the other Endpoints?
Have you set the Roles & Permissions within Strapi?
Example (depending on the Strapi version):
Navigate to SETTINGS - Users & Permissions Plugin.
Click the Public Role.
Scroll down under Permissions, open the Application tab and find the collection type you want to edit.
i.e. Click the checkbox next to find and findone.
Click Save
Check: https://strapi.io/documentation/developer-docs/latest/getting-started/quick-start.html#_7-set-roles-and-permissions
I'm trying to make an api call to k8s api server to update deployment. I can use below to update deployment.
curl -X PATCH --header "Authorization: Bearer $TOKEN" --insecure -H 'Content-Type: application/strategic-merge-patch+json' --data '
{ "spec": { "template": { "spec": { "containers": [ { "name": "nlu","env": [ { "name": "LAST_UPDATE", "value": "123123" } ] } ] } } } }' \
'https://10.1.0.4:6443/apis/apps/v1/namespaces/prod/deployments/nlu?fieldManager=strategic'
But when I use the node.js request module to make request, I got an error like below
message:"read ECONNRESET"
Here is my code
restart()
{
const options = {
url: "http://10.1.0.4:6443",
body: JSON.stringify({
"spec": {
"template": {
"spec": {
"containers": [
{
"name": "nlu",
"env": [
{
"name": "LAST_UPDATE",
"value": "20190909"
}
]
}
]
}
}
}
}),
auth: {
'bearer': "mytoken"
}
};
return new Promise(function(resolve,reject){
request.patch(options, (err , res)=>{
if(err)
{
reject(err)
} else
{
resolve('done')
}
})
})
}
How can I fix this problem, any help would be appreciated?
I found out I missed something so that the k8s server rejected my request. First, the url should start with https instead of http. Second, I was supposed to add content-type "application/strategic-merge-patch+json" in the request head. Third, I also have to add rejectUnauthorized: false in the request to ignore the error when failing to verify the server's identity.
The correct request should be like
const options = {
url: "https://10.1.0.4:6443",
headers: {
"content-type": "application/strategic-merge-patch+json"
},
rejectUnauthorized: false,
body: JSON.stringify({
"spec": {
"template": {
"spec": {
"containers": [
{
"name": "nlu",
"env": [
{
"name": "LAST_UPDATE",
"value": "20190909"
}
]
}
]
}
}
}
}),
auth: {
'bearer': "mytoken"
}
};
Anyone know what I am missing here?
I want my proxy to route all requests to my azure function root URL, to my function.
So that this link https://myfunction.azurewebsites.net/
works the same as this link https://myfunction.azurewebsites.net/MYShinyNewFunction
Here is my proxy.json
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"Root URI to Redirector Trigger Function": {
"matchCondition": {
"route": "/{*path}",
"methods": [
"GET"
]
},
"backendUri": "https://localhost/{*path}"
}
}
}
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"Root URI to Redirector Trigger Function": {
"matchCondition": {
"route": "/{*path}",
"methods": [
"GET"
]
},
"backendUri": "https://myfunction.azurewebsites.net/ActualFunctionName"
}
}
}
Figured it out