<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Luthfi Khusyasy</title>
    <description>The latest articles on Forem by Luthfi Khusyasy (@khusyasy).</description>
    <link>https://forem.com/khusyasy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F717482%2Ffe0e4083-df70-4117-a34e-d95fe4a0bcd8.png</url>
      <title>Forem: Luthfi Khusyasy</title>
      <link>https://forem.com/khusyasy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/khusyasy"/>
    <language>en</language>
    <item>
      <title>Simple auth system using JWT</title>
      <dc:creator>Luthfi Khusyasy</dc:creator>
      <pubDate>Tue, 09 Aug 2022 04:23:00 +0000</pubDate>
      <link>https://forem.com/khusyasy/simple-auth-system-using-jwt-59e5</link>
      <guid>https://forem.com/khusyasy/simple-auth-system-using-jwt-59e5</guid>
      <description>&lt;p&gt;Continuation of the last post, I will try to implement auth system by using JWT (Json Web Token) for my Multiplayer TicTacToe game.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tictactoe.khusyasy.my.id/" rel="noopener noreferrer"&gt;Live Website&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Khusyasy/ws-tictactoe" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What is JWT
&lt;/h2&gt;

&lt;p&gt;JWT is an authorization token created from the backend, passed to the frontend and then the frontend can send this token alongside requests to access protected API routes, it is to make sure that the request from user X is indeed made by user X itself. Usually JWT token is created with expiration time.&lt;/p&gt;

&lt;p&gt;There is a downside here for using JWT, every token that was created and not yet expired can still be used for accessing the protected API routes. Which is usually not what you wanted.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Little disclaimer here: I think JWT itself is actually very simple, but implementing it the right way is the hard part, so if you know a better way or have a correction, please let me know! thanks.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  JWT Revoke Method
&lt;/h2&gt;

&lt;p&gt;So to invalidate and limit the access of the token, from what I have found is mainly 2 methods:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Blacklist/Whitelist the token.&lt;/li&gt;
&lt;li&gt;Use per user secret key for the token.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To be honest I still don't know the pros/cons of those methods, but I'm going to use the second one.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating User Personal Key
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;note: all of the examples shown are simplified version&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bcrypt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generatePersonalKey&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;genSaltSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First the personal key, we need to create a function to generate the keys, like random strings, numbers, or anything. But here I created &lt;code&gt;generatePersonalKey()&lt;/code&gt; by using the &lt;a href="https://www.npmjs.com/package/bcrypt" rel="noopener noreferrer"&gt;bcrypt&lt;/a&gt; packages to create a random salt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;personalKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And for example my &lt;code&gt;UserSchema&lt;/code&gt; (&lt;a href="https://www.npmjs.com/package/mongoose" rel="noopener noreferrer"&gt;mongoose&lt;/a&gt;), we just initialize the personalKey when the user is created. And when user logged out we just regenerate the personalKey, this way the tokens before will always be invalid because they used the different key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating JWT
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jsonwebtoken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;khusyasy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;personalKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1h&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create the token itself I used &lt;a href="https://www.npmjs.com/package/jsonwebtoken" rel="noopener noreferrer"&gt;jsonwebtoken&lt;/a&gt; packages. It is actually very simple like the example above. After that we set the response cookies with the flag &lt;code&gt;httpOnly&lt;/code&gt; so the token cannot be set/get by using javascript on the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking Authorization
&lt;/h2&gt;

&lt;p&gt;When I first read about this I'm very confused, how do you know which key to use, if you can't even read the token?&lt;/p&gt;

&lt;p&gt;Well it turns out we can... just by using &lt;code&gt;decode&lt;/code&gt; to read the payload and getting the user personalKey, and then using the personalKey to verify the token itself. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;verified&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;personalKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// token is verified&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// token is invalid&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is all for today, thank you for reading!&lt;/p&gt;

&lt;h3&gt;
  
  
  packages used:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/bcrypt" rel="noopener noreferrer"&gt;bcrypt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/jsonwebtoken" rel="noopener noreferrer"&gt;jsonwebtoken&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/mongoose" rel="noopener noreferrer"&gt;mongoose&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Flame Chat, a Chat App built using Firebase</title>
      <dc:creator>Luthfi Khusyasy</dc:creator>
      <pubDate>Mon, 08 Aug 2022 07:46:00 +0000</pubDate>
      <link>https://forem.com/khusyasy/flame-chat-a-chat-app-built-using-firebase-39g8</link>
      <guid>https://forem.com/khusyasy/flame-chat-a-chat-app-built-using-firebase-39g8</guid>
      <description>&lt;p&gt;Personal chat app built using React and Firebase!.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chat.khusyasy.my.id/" rel="noopener noreferrer"&gt;Live Website&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Khusyasy/flame-chat" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;note: this is an old post (22 June 2021) from my website, posting for archiving purposes&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Person to person private chat.&lt;/li&gt;
&lt;li&gt;Register and Login using Google Auth.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Objectives
&lt;/h2&gt;

&lt;p&gt;Firebase is a BaaS (Backend as a Service) owned by Google that can help developers quickly develop apps. By using firebase for backend service, I can focus more on the looks and experience or known as UI/UX of the apps. I wanted to learn more about firebase, so I decided to create a Personal Chat App.&lt;/p&gt;

&lt;p&gt;The goal of this project is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Setup Firebase and Firestore.&lt;/li&gt;
&lt;li&gt;Create UI/UX using React.&lt;/li&gt;
&lt;li&gt;Connect Firebase with React.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Setup Firebase and Firestore.
&lt;/h3&gt;

&lt;p&gt;Because this is the first time I used Firebase, I have to learn it first. Searching through Youtube and reading the documentation.&lt;/p&gt;

&lt;p&gt;The process of creating a Firebase project is actually really simple (thanks Google), it took only a couple hours for me.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Create UI/UX using React.
&lt;/h3&gt;

&lt;p&gt;I decided to try out React Bootstrap, it is just Bootstrap but for React. I am actually a little bit familiar with Bootstrap. This should be easy for me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0fv5bewejsdmwyzq46k.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0fv5bewejsdmwyzq46k.jpg" alt="ui ux of the react app" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also decided to use React Context for managing some of the state like user auth and messages. That is to prevent passing props too many layers down the children element.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Connect React with Firestore.
&lt;/h3&gt;

&lt;p&gt;This part is basically just using React with API that is provided by Firestore. Firestore handles all CRUD function. Firestore is a NoSQl database more or less like MongoDB.&lt;/p&gt;

&lt;h2&gt;
  
  
  Techonologies used
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;React JS&lt;/li&gt;
&lt;li&gt;React Context&lt;/li&gt;
&lt;li&gt;React Bootstrap&lt;/li&gt;
&lt;li&gt;Firebase&lt;/li&gt;
&lt;li&gt;Firestore&lt;/li&gt;
&lt;li&gt;Google Auth&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Creating a Quiz Game, Koding Kuiz</title>
      <dc:creator>Luthfi Khusyasy</dc:creator>
      <pubDate>Mon, 08 Aug 2022 07:40:00 +0000</pubDate>
      <link>https://forem.com/khusyasy/creating-a-quiz-game-koding-kuiz-535j</link>
      <guid>https://forem.com/khusyasy/creating-a-quiz-game-koding-kuiz-535j</guid>
      <description>&lt;p&gt;A quiz game about programming, coding, and related stuff. You can test your knowledge about the subject while having fun!.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://quiz.khusyasy.my.id/" rel="noopener noreferrer"&gt;Live Website&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Khusyasy/koding-kuiz" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;note: this is an old post (09 May 2021) from my website, posting for archiving purposes&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Quiz game with multiple categories and difficulties.&lt;/li&gt;
&lt;li&gt;Scoring system.&lt;/li&gt;
&lt;li&gt;Leaderboard system.&lt;/li&gt;
&lt;li&gt;GitHub OAuth integration.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Objectives
&lt;/h2&gt;

&lt;p&gt;I always wanted to create a quiz game about the stuff that i loved, that is tech and programming, and then the player can see how they rank among the other players.&lt;/p&gt;

&lt;p&gt;So to sum it up, the goal of this project is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a quiz game.&lt;/li&gt;
&lt;li&gt;Create an account system.&lt;/li&gt;
&lt;li&gt;Create a leaderboard system.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Create a quiz game.
&lt;/h3&gt;

&lt;p&gt;Firstly, I make a quick quiz game prototype using a framework that I'm currently learning (Vue JS), and this prototype is gonna be the very basic requirement for my quiz game, so I can visualize what would be needed for the quiz game.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0e9vdxz4n56ky3o2040r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0e9vdxz4n56ky3o2040r.png" alt="quiz prototype" width="409" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I actually wanted to create my own API for the questions, but after a while I decided to use a public API, and I found QuizApi, and I have to modify the prototype for a bit so the structure of the quiz is compatible.&lt;/p&gt;

&lt;p&gt;I also decided to keep using Vue JS for this project.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Create an account system.
&lt;/h3&gt;

&lt;p&gt;I'm using GitHub OAuth to save time and my sanity, because by using that, I don't have to deal much about account management and security, GitHub already do that better than me.&lt;/p&gt;

&lt;p&gt;I actually never used GitHub OAuth or any Auth API before, so this is some kind of an amazing new learning experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Create a leaderboard system.
&lt;/h3&gt;

&lt;p&gt;I created a Express JS server and configure MongoDB, and all the usual server configuration stuff, this step is pretty straight forward, that is creating an backend for database CRUD and creating API endpoint like what I usually do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Techonologies used
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MongoDB&lt;/li&gt;
&lt;li&gt;Express JS&lt;/li&gt;
&lt;li&gt;Vue JS&lt;/li&gt;
&lt;li&gt;Vuex&lt;/li&gt;
&lt;li&gt;Node JS&lt;/li&gt;
&lt;li&gt;JWT&lt;/li&gt;
&lt;li&gt;GitHub OAuth&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Making a Link Shortener</title>
      <dc:creator>Luthfi Khusyasy</dc:creator>
      <pubDate>Mon, 08 Aug 2022 07:34:00 +0000</pubDate>
      <link>https://forem.com/khusyasy/making-a-link-shortener-4han</link>
      <guid>https://forem.com/khusyasy/making-a-link-shortener-4han</guid>
      <description>&lt;p&gt;This is a website where you can shorten your link, and make it easier to share with your friends.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sla.khusyasy.my.id/" rel="noopener noreferrer"&gt;Live Website&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Khusyasy/shortlink-app" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;note: this is an old post (07 March 2021) from my website, posting for archiving purposes&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Register and Login to your account.&lt;/li&gt;
&lt;li&gt;Shorten your link in just 1 click.&lt;/li&gt;
&lt;li&gt;View how many times your link has been clicked.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Objectives
&lt;/h3&gt;

&lt;p&gt;I wanted to learn the MERN Stack, so i have to combine what i have learned about React JS and Express JS, i also learn how to do CRUD with MongoDB databases using Mongoose, and using JWT for authentication.&lt;/p&gt;

&lt;h3&gt;
  
  
  Techonologies used
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;MongoDB&lt;/li&gt;
&lt;li&gt;Mongoose&lt;/li&gt;
&lt;li&gt;Express JS&lt;/li&gt;
&lt;li&gt;React JS&lt;/li&gt;
&lt;li&gt;React Router&lt;/li&gt;
&lt;li&gt;Node JS&lt;/li&gt;
&lt;li&gt;JWT&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Multiplayer TicTacToe With Websockets</title>
      <dc:creator>Luthfi Khusyasy</dc:creator>
      <pubDate>Mon, 08 Aug 2022 06:12:00 +0000</pubDate>
      <link>https://forem.com/khusyasy/creating-multiplayer-tictactoe-game-3bc3</link>
      <guid>https://forem.com/khusyasy/creating-multiplayer-tictactoe-game-3bc3</guid>
      <description>&lt;p&gt;Recently I'm trying to learn about websockets and I decided why not create a Multiplayer TicTacToe game using websocket.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tictactoe.khusyasy.my.id/" rel="noopener noreferrer"&gt;Live Website&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Khusyasy/ws-tictactoe" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;note: this is an old post (30 May 2022) from my website, posting for archiving purposes&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Objectives
&lt;/h2&gt;

&lt;p&gt;Learning more about websockets and how to implement them in a realtime game application. Basically websockets are a way to connect to a server for back and forth communication, this is very useful for realtime applications especially in multiplayer games. Also often used in client side websites.&lt;/p&gt;

&lt;p&gt;The goal of this project is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create format for websockets.&lt;/li&gt;
&lt;li&gt;Implement the server.&lt;/li&gt;
&lt;li&gt;Create the game using Vue.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  1. Create format for websockets.
&lt;/h3&gt;

&lt;p&gt;Because I am new to websockets, I am trying to understand the format that will be used to communicate with the server, and to be honest I don't find many resources talking about this, so I am going to try to create my own format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;needed&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the type of message, the data will be used to determine what the server or client should do. For example, if the type is "move", the data will be used to determine which player moved, and where.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;move&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;y&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;col&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The message above means that the user has moved to row number x and column number y.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Implement the server.
&lt;/h3&gt;

&lt;p&gt;I used express to create the server, and I used express-ws to create the websocket so that I can easily use websockets just like other HTTP requests endpoint in express, as an simple example, the following code is used to create the websocket server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ws&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express-ws&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;move&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// do something with data&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But for storing Users and Rooms in the server, I used an array... for now. I think it's okay, because I only make this for learning purposes. If I ever need to store more data, I can easily extend this project to use database.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Create the game using Vue.
&lt;/h3&gt;

&lt;p&gt;This part is basically creating a TicTacToe game but using Vue. I tried to use a new ui library called &lt;a href="https://www.naiveui.com/" rel="noopener noreferrer"&gt;Naive UI&lt;/a&gt;, I think it looks nice, but I don't know if it's the best way to use the library.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgfnq8jg520xzvzooewa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgfnq8jg520xzvzooewa.png" alt="website login page" width="800" height="819"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrduezui83ibn9zgk29u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrduezui83ibn9zgk29u.png" alt="winning at tictactoe" width="800" height="819"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
