Private Routes using VueJs

Quite often in your application, you could come across when certain pages/routes could be accessed by only authenticated users. And then there are other pages, which could be access be any one.

I tend to call them by private routes and public routes. Private Routes requires a certain condition to be met, for example, the user needs to be authenticated. We could also have additional conditions like the user needs to have a certain privilege. If the condition is not met, the user attempting to navigate to the private route needs to be redirected to a common route, usually in public route.

In VueJs, the Navigation guards allows you to intercept the navigations and conditionally evaluate whether or not to accept the redirection or cancel it. While there are multiple ways to intercept the navigation process, per-route, in-component, the easiest way would be to use the the Global Guards.

Global Before Guards

The beforeEach guard method is probably the most common approach to handle navigations. The method is called each time when a new navigation starts.

You could add the validation code in the beforeEach method to ensure only the validated users access the pages.

const router = new VueRouter({
  routes,
});

router.beforeEach((to, from, next) => {
   // Your validation logic goes here.
});


The beforeEach Method accepts 3 parameters.

  • to : The future Route
  • from : the current Route
  • next : a function that should be called to resolve the route successfully.

Real World Scenario

Let us consider a real world scenario. You have couple of routes in your application.

const routes = [
  {
    path: "/",
    name: "Default",
    component: Default
  },
  {
    path: "/login",
    name: "Login",
    component: Login
  },
  {
    path: "/dashboard",
    name: "Dashboard",
    component: Dashboard
  },
];

Ideally, you would like the Default and Login to be accessed by anyone. However, the Dashboard should be accessed only by authenticated users only.

We begin by including this very bit of logic in our route definition. We could use the meta tags for including additional information. Redefining our routes now,

const routes = [
  {
    path: "/",
    name: "Default",
    component: Default,
    meta: {
      requiresAuth: false,
    },
  },
  {
    path: "/login",
    name: "Login",
    component: Login,
    meta: {
      requiresAuth: false,
    },
  },
  {
    path: "/dashboard",
    name: "Dashboard",
    component: Dashboard,
    meta: {
      requiresAuth: true,
    },
  },
];

As you can observe, we have added a requiresAuth flag within the meta information of routes. With this in place, we could now alter our beforeEach code as following.

router.beforeEach((to, from, next) => {
  if (to.matched.some((record) => record.meta.requiresAuth)) {
    if (isAuthenticated()) {
      next();
    } else {
      next("/");
    }
  } else {
    next();
  }
});

The method now checks if the to route has the meta information flag of requiresAuth set to true and if so, calls your custom isAuthenticated method to verify if the user is authenticated to access the page.

If the user is authenticated to access the page, the next() method is called to complete the navigation successfully. Otherwise, you override the to route and navigate away to a custom route, in this case using next(“/”).

That’s all your require for creating private routes using VueJs. If you would like to see the complete code, you could find the same here in my Github.

Evil Code #011 : Tuples

It has been long since I wrote a post in Evil Code series. So here is a short one, using the Tuples which was introduced in C# 7.X.

“introduced in C# 7.x” . You must be wondering why I used that phrase. Tuples was there before 7.x right ? Well, the answer is both yes and no. Tuples did exist before 7.x, but the one introduced in 7.x isn’t exactly the same. This newer version is a struct called System.ValueTuple and are noticeably different from its predecesoor in following ways.

  • System.ValueTuple is a struct, while System.Tuple is a reference type.
  • System.ValueTuple is mutable, while System.Tuple is not.
  • System.ValueTuple exposes items via Fields, while System.Tuple exposes items via properties.

You might have already seen a thousand articles on Tuples and have used them in your code base. So I would not go into further details on semantics and usages, but we will explore a special case.

Consider the following code.

var tuple1 = (Item1:1,Item2:2);
var tuple2 = (1,2);
var tuple3 = (Item2:2,Item1:1);

What would be the output of above code ?

Well, it would not even compile. The last would throw an error.

CS8125 Tuple element name 'Item2' is only allowed at position 2.
CS8125 Tuple element name 'Item1' is only allowed at position 1.

Why is it so ? Tuples can be broadly categorized in two ways – tuple literal and tuple types.

Tuple literals has a value and an optional name, while tuple typeshave type and optional name. In both cases, the name is optional and could be anything, except when the naming pattern uses the ItemN syntax.

These are reserved names which the tuple reserves for unnamed Tuple. You could use them as well, however, you are not allowed to alter the order.

Every element in the tuple could be accessed by the name if present, or its position. For acessing the Tuple element with position, .Net uses the naming convension ItemN where N is the position in the Tuple (1 based index).

The first element in the Tuple has to be Item1, the second Item2 and so on. If you alter the naming convention and use Item2 as the first element, the compiler would complain as shown above.

If you are attempting to name the first element as Item2, you are basically creating an ambiguity (should use the word confusion). This is why the naming convension prohibits such a pattern.

That was a rather a simple one right ? But that is the thing I like about the Evil Code series. Most of them are quite simple, but somewhere in the details, there are hidden facts which one as a developer needs to be aware of.

Real World Demo Applications

One of the recent projects I started on Github is NT – my own version of Thinkster’s Real World repos. The idea, much like the original idea, is to pick up a project topic and implement it in every language/framework i learn.

As a beginning, I have created the Web API using .Net 5 Preview with MongoDb as the database. The client is being currently developed under following platforms.

  • ReactJs
  • WPF

I also plan to the client implement with VueJs , Flutter/Dart and Xamarin in immediate future. Rest of the frameworks/languages would be added as and when I explore them. I am tempted to simultaneously implement the projects, rather than completing them sequentially due to personal reasons.

I am also making use of supporting frameworks like DocFx for documentations and Github Actions for CI/CD. The deployed documentation (generated with Docfx to begin with) would be deployed in Github Pages.

If you are interested in the project, please do follow it here in my Github.

Getting started with DocFx

I have been lately pretty impressed with the DocFx, Microsoft’s static documentation generator. In this blog post, I thought I would outline how easy it is to configure the DocFx for generating documentation for your project.

Assumption : Project already has Xml documentations enabled and the code have the necessary comments.

Step 1 : Install Chocolatey

  • Head over to Chocolatey’s official website and copy the command given in the getting started page.
  • Open the Powershell with Administrative prileges and executed the command copied.

For reference, the command is as follows.

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

Step 2 : Install Docfx

  • Install Doxfx with following command
cinst docfx -y

Step 3 : Generate DocFx Project

  • Generate Sample DocFx Project for your Project Documentation with the following command.
docfx init -q

Or if you would like to dictate the name for your project.

docfx init -q -o <DocumentationProjectName>

This would generate sample project for your purpose.

Step 4: Specify Project Details

The next step is to specify the location of your Project Files. This has to be mentioned in the docfx.json file.

I am including only the relavant part of docfx.json.

"src": [
        {
          "files": "src/infrastructure/Nt.Infrastructure.UI/**.csproj",
          "cwd": "..",
          "src": "../.."
        }

As you can observe, we have used base path using the src and cwd values, and use the files to specify the projects under consideration.

Step 5 : Build and Generate your documentation website.

That’s all the configuration you would need. Rest of the magic would be done by Docfx for you. To build the project and generate the website, you need to use the following command.

docfx --serve

And there you have it, you have your documentation up and running in the development server. You could access it via (http://localhost:8080/).

We will explore more features of DocFx and related configuration in later post, but surely, this would get you started.

Mocking User.Identity.Name

One of the other issue you might encounter while unit testing your Controller is when you dealing with Identity. Consider the following action method.

public async Task<BarResponse> Foo(BarRequest user)
{
    if (ModelState.IsValid)
    {
        try
        {
            var userName = User.Identity.Name;
            // Do Task
            return new BarResponse{
                
            };
        }
        catch (Exception ex)
        {
            return new BarResponse { ErrorMessage = ex.Message};
        }
    }
    else
    {
        var errrorMessages = ModelState.Values.SelectMany(x => x.Errors.Select(c => c.ErrorMessage));
        return new BarResponse { ErrorMessage = string.Join(Environment.NewLine, errrorMessages), modelState = ModelState };
    }
}

One of the issues is how do one mock the User.Identity.Name. The trick lies in creating a Test instance of DefaultHttpContext and replace with Controller’s context. Let’s write an Unit Test for the above code.

var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
{
    new Claim(ClaimTypes.Name, "anuviswan"),
    
}, "mock"));
userController.ControllerContext.HttpContext = new DefaultHttpContext() { User = user };

Guess what, I spend atleast 5 hours for figuring out this. Some of the harder days in life.