Sveletkit Redirect doesn't seem to work for me - redirect

I keep having an issue with returning a redirect from the load method in sveltekit. I'm ready to quit. So this simple little redirect doesn't see to work for me in __layout.svelte
export async function load() {
let user = false
if (!user) {
return {
status: 301,
redirect: '/login'
}
} else {
return {}
}
}
And I get the screenshot below. Nothing I do seems to work with redirects. Any suggestions as to why I can't seem to get this simple thing to work.

Solved the problem. Because it's __layout.svelte the code needed a check for the url.pathname otherwise it seems to act like a loop.
The solution:
export async function load({ url }) {
let user = false
if (!user && !url.pathname.includes('/login')) {
return {
status: 301,
redirect: '/login'
}
} else if (user && url.pathname.includes('/login')){
return {
status: 301,
redirect: '/'
}
} else {
return {}
}
}

Related

Service worker returning Offline page instead of 404 page when non-existant file is requested

I'm using this service worker for caching and offline mode.
when I am already on any existing page of my website and I request a non-existent page, the Offline page is served instead of the 404 page.
If, on the other hand, I close and reopen the browser and immediately request a non-existent page of my website, the 404 page is served correctly.
I suspect it has to do with these last few lines of the code
if(!matching || matching.status == 404) { return cache.match("/service/offline/"); but i don't know how to fix this problem. Can you help me please?
Here's the full service worker:
self.addEventListener("install", function(event) {
event.waitUntil(preLoad());
});
var preLoad = function(){
console.log("Installing web app");
return caches.open("offline").then(function(cache) {
console.log("caching index and important routes");
return cache.addAll([
'/assets/css/about.min.css',
'favicon.ico',
'/assets/js/script.js',
'manifest.webmanifest.webmanifest',
'/',
'/about/',
'/contact/',
'/service/offline/'
]);
});
};
self.addEventListener("fetch", function(event) {
event.respondWith(checkResponse(event.request).catch(function() {
return returnFromCache(event.request);
}));
event.waitUntil(addToCache(event.request));
});
var checkResponse = function(request){
return new Promise(function(fulfill, reject) {
fetch(request).then(function(response){
if(response.status !== 404) {
fulfill(response);
} else {
reject();
}
}, reject);
});
};
var addToCache = function(request){
return caches.open("offline").then(function (cache) {
return fetch(request).then(function (response) {
console.log(response.url + " was cached");
return cache.put(request, response);
});
});
};
var returnFromCache = function(request){
return caches.open("offline").then(function (cache) {
return cache.match(request).then(function (matching) {
if(!matching || matching.status == 404) {
return cache.match("/service/offline/");
} else {
return matching;
}
});
});
};

Error laravel 6 axios: No 'Access-Control-Allow-Origin'

please I need you to help me with a problem in Server xampp, laravel 6 with axios, apparently it doesn't allow me to request ajax. attached image for more detail. Thanks in advance.
methods: {
loadEstados() {
axios.get(`http://localhost/estados/pais/${this.selected_pais}`).then((response) => {
this.careers = response.data;
})
.catch(function (error) {
console.log(error);
});
Route::get('estados/pais/{pais_id}', 'UsuarioController#getEstadosByPais');
public function getEstadosByPais($pais_id)
{
if ($request->ajax()) {
$estados = Estado::where('id', $pais_id)->get();
foreach ($estados as $estado) {
$estadoArray[$estado->id] = $estado->esta_nombre;
}
return response()->json($estadoArray);
}
//
}
browser error
I found the solution, the problem was how i put the address
in the web.php
Route::get('estados/pais/', 'UsuarioController#getEstadosByPais');
in the file js
if (this.selected_pais !="") {
axios.get(`http://127.0.0.1:80/estados/pais`,
{params: {pais_id: this.selected_pais} }).then((response) => {
this.estados = response.data;
document.getElementById('estado').disabled =false;
});
}
in the file controller
public function getEstados(Request $request)
{
if ($request->ajax()) {
$estados = Estado::where('id', $request->pais_id)->get();
foreach ($estados as $estado) {
$estadoArray[$estado->id] = $estado->esta_nombre;
}
return response()->json($estadoArray);
}
}
Including port if necessary
thank you very much

Redirect to requested page after login using vue-router

In my application some routes are just accessible for authenticated users.When a unauthenticated user clicks on a link, for which he has to be signed in, he will be redirected to the login component.
If the user logs in successfully, I would like to redirect him to the URL he requested before he had to log in. However, there also should be a default route, in case the user did not request another URL before he logged in.
How can I achieve this using vue-router?
My code without redirect after login
router.beforeEach(
(to, from, next) => {
if(to.matched.some(record => record.meta.forVisitors)) {
next()
} else if(to.matched.some(record => record.meta.forAuth)) {
if(!Vue.auth.isAuthenticated()) {
next({
path: '/login'
// Redirect to original path if specified
})
} else {
next()
}
} else {
next()
}
}
)
My login function in my login component
login() {
var data = {
client_id: 2,
client_secret: '**************',
grant_type: 'password',
username: this.email,
password: this.password
}
// send data
this.$http.post('oauth/token', data)
.then(response => {
// authenticate the user
this.$auth.setToken(response.body.access_token,
response.body.expires_in + Date.now())
// redirect to route after successful login
this.$router.push('/')
})
}
This can be achieved by adding the redirect path in the route as a query parameter.
Then when you login, you have to check if the redirect parameter is set:
if IS set redirect to the path found in param
if is NOT set you can fallback on root.
Put an action to your link for example:
onLinkClicked() {
if(!isAuthenticated) {
// If not authenticated, add a path where to redirect after login.
this.$router.push({ name: 'login', query: { redirect: '/path' } });
}
}
The login submit action:
submitForm() {
AuthService.login(this.credentials)
.then(() => this.$router.push(this.$route.query.redirect || '/'))
.catch(error => { /*handle errors*/ })
}
I know this is old but it's the first result in google and for those of you that just want it given to you this is what you add to your two files. In my case I am using firebase for auth.
Router
The key line here is const loginpath = window.location.pathname; where I get the relative path of their first visit and then the next line next({ name: 'Login', query: { from: loginpath } }); I pass as a query in the redirect.
router.beforeEach((to, from, next) => {
const currentUser = firebase.auth().currentUser;
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
if (requiresAuth && !currentUser) {
const loginpath = window.location.pathname;
next({ name: 'Login', query: { from: loginpath } });
} else if (!requiresAuth && currentUser) next('menu');
else next();
});
Login Page
No magic here you'll just notice my action upon the user being authenticated this.$router.replace(this.$route.query.from); it sends them to the query url we generated earlier.
signIn() {
firebase.auth().signInWithEmailAndPassword(this.email, this.password).then(
(user) => {
this.$router.replace(this.$route.query.from);
},
(err) => {
this.loginerr = err.message;
},
);
},
I am going to be fleshing out this logic in more detail but it works as is. I hope this helps those that come across this page.
Following on from Matt C's answer, this is probably the simplest solution but there were a few issues with that post, so I thought it best to write a complete solution.
The destination route can be stored in the browser's session storage and retrieved after authentication. The benefit of using session storage over using local storage in this case is that the data doesn't linger after a broswer session is ended.
In the router's beforeEach hook set the destination path in session storage so that it can be retrieved after authentication. This works also if you are redirected via a third party auth provider (Google, Facebook etc).
router.js
// If user is not authenticated, before redirecting to login in beforeEach
sessionStorage.setItem('redirectPath', to.path)
So a fuller example might look something like this. I'm using Firebase here but if you're not you can modify it for your purposes:
router.beforeEach((to, from, next) => {
const requiresAuth = to.matched.some(x => x.meta.requiresAuth);
const currentUser = firebase.auth().currentUser;
if (requiresAuth && !currentUser) {
sessionStorage.setItem('redirectPath', to.path);
next('/login');
} else if (requiresAuth && currentUser) {
next();
} else {
next();
}
});
login.vue
In your login method, after authetication you will have a line of code that will send the user to a different route. This line will now read the value from session storage. Afterwards we will delete the item from session storage so that it is not accidently used in future (if you the user went directly to the login page on next auth for instance).
this.$router.replace(sessionStorage.getItem('redirectPath') || '/defaultpath');
sessionStorage.removeItem('redirectPath');
A fuller example might look like this:
export default Vue.extend({
name: 'Login',
data() {
return {
loginForm: {
email: '',
password: ''
}
}
},
methods: {
login() {
auth.signInWithEmailAndPassword(this.loginForm.email, this.loginForm.password).then(user => {
//Go to '/defaultpath' if no redirectPath value is set
this.$router.replace(sessionStorage.getItem('redirectPath') || '/defaultpath');
//Cleanup redirectPath
sessionStorage.removeItem('redirectPath');
}).catch(err => {
console.log(err);
});
},
},
});
If route guard is setup as below
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!loggedIn) {
next({
path: "/login",
query: { redirect: to.fullPath }
});
} else {
next();
}
} else {
next();
}
});
The redirect query can be extracted and used upon successful login
let searchParams = new URLSearchParams(window.location.search);
if (searchParams.has("redirect")) {
this.$router.push({ path: `${searchParams.get("redirect")}` });
} else this.$router.push({ path: "/dashboard" });
Another quick and dirty option would be to use local storage like the following:
In your beforeEach, before you redirect to login place the following line of code to save the initial requested path to local storage:
router.js
// If user is not authenticated, before redirecting to login
localStorage.setItem('pathToLoadAfterLogin', to.path)
Then in your login component, upon succesful login, you can redirect to the localStorage variable that you previously created:
login.vue
// If user login is successful, route them to what they previously requested or some default route this.$router.push(localStorage.getItem('pathToLoadAfterLogin') || 'somedefaultroute');
Much easier with this library
and login function is
let redirect = this.$auth.redirect();
this.$auth
.login({
data: this.model,
rememberMe: true,
redirect: { name: redirect ? redirect.from.name : "homepage", query: redirect.from.query },
fetchUser: true
})
This will help you #Schwesi .
Router.beforeEach(
(to, from, next) => {
if (to.matched.some(record => record.meta.forVisitors)) {
if (Vue.auth.isAuthenticated()) {
next({
path: '/feed'
})
} else
next()
}
else if (to.matched.some(record => record.meta.forAuth)) {
if (!Vue.auth.isAuthenticated()) {
next({
path: '/login'
})
} else
next()
} else
next()
}
);
This worked for me.
this.axios.post('your api link', {
token: this.token,
})
.then(() => this.$router.push(this.$route.query.redirect || '/dashboard'))
In Vue2 if someone has a routing and guarded some groups of routes. I solved this way.
function webGuard(to, from, next) {
if (!store.getters["auth/authenticated"]) {
sessionStorage.setItem("redirect", to); // hear I save the to
next("/login");
} else {
next();
}
}
Vue.use(VueRouter);
export default new VueRouter({
mode: "history",
hash: false,
routes: [
{
path: "/",
component: Home,
children: [
{ path: "", redirect: "home" },
...
...
],
beforeEnter: webGuard
},]
when you login
this.signIn({ email: test#gmail.com, password: 123 })
.then((res) => {
var redirectPath = sessionStorage.getItem('redirect');
sessionStorage.removeItem('redirect');
this.$router.push(redirectPath?redirectPath:"/dashboard");
})

How to retrieve value from Storage and user it somewhere else in Ionic 2

I am new to Ionic 2 and Promises and having some issues.
My Ionic 2 app saves an auth_token to the local storage:
this.storage.set('auth_token', auth_token);
Then later in my secured component I want to check if a token is set, but I don't know how to do this.
I tried this:
authenticate() {
var auth_token = this.storage.get('auth_token').then((val) => {
return val;
});
}
Then from somewhere else I called:
console.log(this.auth.authenticate);
But it won't work, it just returns the function itself.
How do I return the token from my authenticate method?
Check here for chaining of promises.
In your authenticate() function return the original promise call and use then in the function in the other location
authenticate() {
return this.storage.get('auth_token').then((val) => {
return val;
});
}
When caling authenticate...
this.auth.authenticate().then((val)=>{
console.log(val);
}).catch(error=>{
//handle error
});
You just want to check or do you need to return it?
If it's only checking you can do this:
authenticate() {
this.storage.get('auth_token').then((val) => {
if(val){ ... } // or console.log it if it's just what you need.
}
}
If you need to return, create a promise like this:
authenticate = (): Promise<{exists: boolean, auth: any}> =>{
return new Promise<{exists: boolean, auth: any}>(res =>{
this.storage.get('auth_token').then((val) => {
if(val){
res({exists: true, auth: val});
} else {
res({exists: false, auth: val});
}
}
})
}
and later call authenticate().then(res =>{}) and access the object returned in res.
EDIT
As commented by Suraj and tested now, it doesn't need to be encapsulated inside a new promise, so if you need to return it just use the method Suraj suggested.

mvc6 unauthorized results in redirect instead

I have been trying to prevent the redirect when I return an NotAuthorized IActionResult from a Controller, but regardless of my attempts, NotAuthorized gets translated to a Redirect.
I have tried what is mentioned here (same issue, using older beta framework, I use 1.0.0-rc1-final). I do not have the Notifications namespace (has been removed in rc1-final).
This is my Login Controller:
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
return Ok(model);
}
if (result.IsLockedOut)
{
return new HttpStatusCodeResult((int)HttpStatusCode.Forbidden);
}
else
{
return HttpUnauthorized();
}
}
return HttpUnauthorized();
}
In Startup.cs I have tried variations over this:
services.Configure<CookieAuthenticationOptions>(o =>
{
o.LoginPath = PathString.Empty;
o.ReturnUrlParameter = PathString.Empty;
o.AutomaticChallenge = false;
});
Everytime a login fails (please ignore that the password is returned on Ok) and should result in an empty 401 page, I get a redirection to /Account/Login instead. What is the trick here?
The solution is not to configure CookieAuthenticationOptions directly, but do it via IdentityOptions like this:
services.Configure<IdentityOptions>(o =>
{
o.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents()
{
OnRedirectToLogin = ctx =>
{
if (ctx.Response.StatusCode == (int)HttpStatusCode.Unauthorized)
{
return Task.FromResult<object>(null);
}
ctx.Response.Redirect(ctx.RedirectUri);
return Task.FromResult<object>(null);
}
};
});
Taken from here ( Shawn Wildermuth --> ASP.NET 5 Identity and REST APIs --> Comment of "Mehdi Hanafi") and tested the API with Postman
config.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents()
{
OnRedirectToLogin = ctx =>
{
if (ctx.Request.Path.StartsWithSegments("/api") &&
ctx.Response.StatusCode == 200)
{
ctx.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
return Task.FromResult<object>(null);
}
else
{
ctx.Response.Redirect(ctx.RedirectUri);
return Task.FromResult<object>(null);
}
}
};
from Identity 2.0,
you'd need to add:
using Microsoft.AspNetCore.Authentication.Cookies;
and in ConfigureServices:
services.ConfigureApplicationCookie(options =>
{
options.Events = new CookieAuthenticationEvents
{
OnRedirectToLogin = (x =>
{
if (x.Request.Path.StartsWithSegments("/api") && x.Response.StatusCode == 200)
x.Response.StatusCode = 401;
return Task.CompletedTask;
}),
OnRedirectToAccessDenied = (x =>
{
if (x.Request.Path.StartsWithSegments("/api") && x.Response.StatusCode == 200)
x.Response.StatusCode = 403;
return Task.CompletedTask;
})
};
});
the segments check should of course be adjusted to your routes.
If you have some pages for which the redirect is desired and other URLs that should not have a redirect, see this question for a solution that uses the default redirect logic only for non-API URLs:
Suppress redirect on API URLs in ASP.NET Core