<?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>DEV Community: Seamoon Pandey</title>
    <description>The latest articles on DEV Community by Seamoon Pandey (@seamoonpandey).</description>
    <link>https://dev.to/seamoonpandey</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1029100%2F5a0775c4-c1e5-4162-a0f7-ca67ae2b375a.jpg</url>
      <title>DEV Community: Seamoon Pandey</title>
      <link>https://dev.to/seamoonpandey</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/seamoonpandey"/>
    <language>en</language>
    <item>
      <title>My laptop told me to load the kernel first, so I did (a missing-kernel horror story on EndeavourOS)</title>
      <dc:creator>Seamoon Pandey</dc:creator>
      <pubDate>Mon, 22 Jun 2026 09:24:26 +0000</pubDate>
      <link>https://dev.to/seamoonpandey/my-laptop-told-me-to-load-the-kernel-first-so-i-did-a-missing-kernel-horror-story-on-endeavouros-58m8</link>
      <guid>https://dev.to/seamoonpandey/my-laptop-told-me-to-load-the-kernel-first-so-i-did-a-missing-kernel-horror-story-on-endeavouros-58m8</guid>
      <description>&lt;p&gt;So I rebooted my machine like a normal person and got slapped with a blue GRUB screen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error: file '/boot/vmlinuz-linux-lts' not found.
you need to load the kernel first
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool. Very helpful. Load the kernel first. With what, GRUB? My good looks?&lt;/p&gt;

&lt;p&gt;I dived deep into the issue just to find this was a pretty common issue caused due to some update cancellations in between update sessions breaking the packages(most probably a patience issue) as well as spent almost  an extra of about half an hour session with my claude for more specific information on the issue or rather solution.&lt;/p&gt;

&lt;p&gt;If you're reading this because you got the same message, good news: your system is almost certainly fine and you do not need to reinstall anything. I went through the full panic arc so you don't have to, and here's roughly how it went.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, the dumb mistake everyone makes
&lt;/h2&gt;

&lt;p&gt;I knew the rough shape of the fix from somewhere in the back of my brain: boot a live USB, chroot in, fix it. So naturally, sitting at the &lt;code&gt;grub&amp;gt;&lt;/code&gt; prompt, I confidently typed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;grub&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;mount /dev/sdXn /mnt
&lt;span class="go"&gt;error: can't find command `mount'.
&lt;/span&gt;&lt;span class="gp"&gt;grub&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;arch-chroot /mnt
&lt;span class="go"&gt;error: can't find command `arch-chroot'.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GRUB just stared at me. Turns out the GRUB shell is not Linux. It has its own tiny set of commands, and &lt;code&gt;mount&lt;/code&gt; and &lt;code&gt;arch-chroot&lt;/code&gt; are not among them. Those are things you run later, from an actual live environment. Lesson one: the blue prompt is not a terminal, stop treating it like one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the error actually means
&lt;/h2&gt;

&lt;p&gt;GRUB's whole job is to grab a kernel and its initramfs, load them into memory, and hand off. The error shows up when GRUB has a menu entry pointing at a kernel file, in my case &lt;code&gt;/boot/vmlinuz-linux-lts&lt;/code&gt;, but that file simply isn't there. Nothing to load means nothing to boot. Hence the passive-aggressive "you need to load the kernel first."&lt;/p&gt;

&lt;p&gt;So the real mystery is: where did my kernel go?&lt;/p&gt;

&lt;h2&gt;
  
  
  Poking around from the GRUB shell
&lt;/h2&gt;

&lt;p&gt;Before doing anything drastic you can actually snoop on your disks from &lt;code&gt;grub&amp;gt;&lt;/code&gt;. List partitions with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I got back something like &lt;code&gt;(hd0,gpt5) (hd0,gpt4) (hd0,gpt3) (hd0,gpt2) (hd0,gpt1)&lt;/code&gt;. Then you just go fishing through them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;hd0,gpt5&lt;span class="o"&gt;)&lt;/span&gt;/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The one that spits out &lt;code&gt;boot/ etc/ home/ usr/ var/ ...&lt;/code&gt; is your Linux root. Mine was gpt5. Then the moment of truth:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;hd0,gpt5&lt;span class="o"&gt;)&lt;/span&gt;/boot/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;code&gt;/boot&lt;/code&gt; contained... &lt;code&gt;amd-ucode.img&lt;/code&gt; and &lt;code&gt;grub/&lt;/code&gt;. That's it. No &lt;code&gt;vmlinuz-linux&lt;/code&gt;. No &lt;code&gt;initramfs-linux.img&lt;/code&gt;. My kernel had ghosted me. (Also, if you see an empty &lt;code&gt;boot/efi&lt;/code&gt; folder here, relax, that's just an unmounted mountpoint, not the problem.)&lt;/p&gt;

&lt;p&gt;At this point I genuinely considered just wiping the whole thing and starting fresh with some calmer distro. Do not do this. I'll get to why.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making the rescue USB without a second computer
&lt;/h2&gt;

&lt;p&gt;I only have the one laptop, which felt like a dealbreaker until I remembered it dual-boots Windows, and the Windows install was sitting there completely untouched on its own partition. So I booted into Windows straight from the BIOS boot menu (mash F12 / F2 / Esc at power-on depending on your machine), downloaded the EndeavourOS ISO, and flashed it to a USB stick with Rufus.&lt;/p&gt;

&lt;p&gt;If you run EndeavourOS, grab the EndeavourOS ISO. Vanilla Arch, grab the Arch ISO. Matching your actual distro saves you keyring headaches later.&lt;/p&gt;

&lt;h2&gt;
  
  
  The live USB also tried to ruin my day
&lt;/h2&gt;

&lt;p&gt;Booted the USB, picked the friendly default entry ("open source drivers, all GPUs"), and watched the screen blink at me forever. Black, blink, black, blink, nothing. This is apparently a beloved tradition on laptops with NVIDIA graphics: the normal graphical boot just refuses to come up.&lt;/p&gt;

&lt;p&gt;The fix is the entry nobody reads: &lt;strong&gt;fallback / nomodeset&lt;/strong&gt;. Reboot the USB, pick that, and it boots ugly but functional. That got me to a desktop. If you're stuck blinking, that's your move.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally, the actual repair
&lt;/h2&gt;

&lt;p&gt;Opened a terminal and ran the one command that changes nothing and tells you everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lsblk &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows your partitions and their filesystems. I was looking for two things: my root partition (ext4, helpfully labeled &lt;code&gt;endeavouros&lt;/code&gt;) and my EFI partition (small, FAT32). Mine were &lt;code&gt;nvme0n1p5&lt;/code&gt; and &lt;code&gt;nvme0n1p1&lt;/code&gt;. Yours might be &lt;code&gt;sda5&lt;/code&gt; / &lt;code&gt;sda1&lt;/code&gt; on an older SATA drive. Use your real names, not mine.&lt;/p&gt;

&lt;p&gt;Then mount everything and jump in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mount /dev/nvme0n1p5 /mnt
&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /mnt/boot/efi
&lt;span class="nb"&gt;sudo &lt;/span&gt;mount /dev/nvme0n1p1 /mnt/boot/efi
&lt;span class="nb"&gt;sudo &lt;/span&gt;arch-chroot /mnt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the prompt flips to something like &lt;code&gt;[root@EndeavourOS /]#&lt;/code&gt;, you're now living inside your installed system instead of the USB. This is where the real commands work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The plot twist
&lt;/h2&gt;

&lt;p&gt;I figured I'd just reinstall the kernel and go to bed. But first I checked what was actually installed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pacman &lt;span class="nt"&gt;-Q&lt;/span&gt; linux linux-lts mkinitcpio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And got this beautiful nonsense:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;linux 7.0.12.arch1-1
linux-lts 6.18.36-1
error: package 'mkinitcpio' was not found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There it was. According to pacman, both kernels were perfectly installed. But &lt;code&gt;mkinitcpio&lt;/code&gt; was gone. And &lt;code&gt;mkinitcpio&lt;/code&gt; is the thing that actually builds your initramfs and gets the kernel images written into &lt;code&gt;/boot&lt;/code&gt; during install. No &lt;code&gt;mkinitcpio&lt;/code&gt; means the kernel package "installs" but never produces the files GRUB needs. The database lies to your face while &lt;code&gt;/boot&lt;/code&gt; sits there empty.&lt;/p&gt;

&lt;p&gt;How does &lt;code&gt;mkinitcpio&lt;/code&gt; go missing? Usually an upgrade that got interrupted, a &lt;code&gt;/boot&lt;/code&gt; that filled up mid-write, or a cleanup / package removal that took more than you meant it to. I genuinely don't remember which crime I committed, but the result was the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix that finally worked
&lt;/h2&gt;

&lt;p&gt;Install the missing piece, then reinstall the kernels so the hooks actually fire this time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pacman &lt;span class="nt"&gt;-S&lt;/span&gt; mkinitcpio
pacman &lt;span class="nt"&gt;-S&lt;/span&gt; linux linux-lts amd-ucode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Say yes to the reinstall. (I'm on AMD, hence &lt;code&gt;amd-ucode&lt;/code&gt;. Intel folks want &lt;code&gt;intel-ucode&lt;/code&gt;. Don't want the LTS kernel? Drop &lt;code&gt;linux-lts&lt;/code&gt; and the dead menu entry disappears on its own.)&lt;/p&gt;

&lt;p&gt;If pacman starts whining about keyrings or signatures, refresh them first with &lt;code&gt;pacman -Sy archlinux-keyring&lt;/code&gt; (add &lt;code&gt;endeavouros-keyring&lt;/code&gt; on EndeavourOS) and try again.&lt;/p&gt;

&lt;p&gt;Then check that the files actually showed up this time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /boot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally, the good stuff:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vmlinuz-linux                     vmlinuz-linux-lts
initramfs-linux.img               initramfs-linux-lts.img
initramfs-linux-fallback.img      initramfs-linux-lts-fallback.img
amd-ucode.img                     grub/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A populated &lt;code&gt;/boot&lt;/code&gt;. Chef's kiss. The kernels exist again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping it up
&lt;/h2&gt;

&lt;p&gt;Tell GRUB about its newly recovered kernels, then get out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;grub-mkconfig &lt;span class="nt"&gt;-o&lt;/span&gt; /boot/grub/grub.cfg
&lt;span class="nb"&gt;exit
sudo &lt;/span&gt;umount &lt;span class="nt"&gt;-R&lt;/span&gt; /mnt
reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pull the USB on the way down. It booted straight into my normal GRUB menu and into a working desktop like nothing had happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  While you're in there, two quick checks
&lt;/h2&gt;

&lt;p&gt;Run &lt;code&gt;df -h /boot&lt;/code&gt; and make sure it isn't basically full, because a stuffed &lt;code&gt;/boot&lt;/code&gt; is a great way to cause this exact mess again. And if you're paranoid, &lt;code&gt;mkinitcpio -P&lt;/code&gt; rebuilds every initramfs by hand, though the kernel reinstall already does it for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stuff I'd tell past me
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;grub&amp;gt;&lt;/code&gt; prompt is not bash. Stop typing Linux commands into it.&lt;/li&gt;
&lt;li&gt;Don't yank the power during a &lt;code&gt;pacman -Syu&lt;/code&gt;. Let kernel upgrades finish, especially on a laptop.&lt;/li&gt;
&lt;li&gt;Keep an eye on &lt;code&gt;/boot&lt;/code&gt; free space.&lt;/li&gt;
&lt;li&gt;Read what pacman is about to remove before hitting yes. If it wants to take &lt;code&gt;linux&lt;/code&gt; or &lt;code&gt;mkinitcpio&lt;/code&gt; with it, that's your sign to stop.&lt;/li&gt;
&lt;li&gt;Keep a flashed live USB in a drawer. It turns "my laptop is bricked" into "ugh, fifteen minutes."&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  And please don't just reinstall
&lt;/h2&gt;

&lt;p&gt;I almost did. It feels clean when you're frustrated. But reinstalling throws away all your config, takes way longer than the repair, and worst of all, fiddling with partitions next to a Windows install is a fantastic way to accidentally delete Windows too. The repair touches exactly two things: the kernel files and the GRUB config. The reinstall touches your entire disk. You need the same USB stick either way, so just try the repair first.&lt;/p&gt;

&lt;p&gt;My system, my dotfiles, my Windows install, all completely fine the whole time. I was just missing a couple of files and one very important package. That's it.&lt;/p&gt;

</description>
      <category>archlinux</category>
      <category>endeavouros</category>
      <category>troubleshooting</category>
    </item>
    <item>
      <title>I Forgot My Linux Password — And Reset It in 5 Minutes</title>
      <dc:creator>Seamoon Pandey</dc:creator>
      <pubDate>Tue, 09 Jun 2026 21:55:31 +0000</pubDate>
      <link>https://dev.to/seamoonpandey/i-forgot-my-linux-password-and-reset-it-in-5-minutes-2adj</link>
      <guid>https://dev.to/seamoonpandey/i-forgot-my-linux-password-and-reset-it-in-5-minutes-2adj</guid>
      <description>&lt;p&gt;Most Linux users assume their login password is the primary barrier protecting their system. Then one day they forget it.&lt;/p&gt;

&lt;p&gt;The surprising part? On many Linux distributions, resetting a forgotten password is remarkably easy if you have physical access to the machine.&lt;/p&gt;

&lt;p&gt;This isn't a vulnerability. It's a fundamental aspect of how local system administration works on Linux.&lt;/p&gt;

&lt;p&gt;Let's explore why password recovery works, how it's done, and what it teaches us about Linux security.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Situation
&lt;/h2&gt;

&lt;p&gt;Imagine you've been away from your laptop for a few weeks.&lt;/p&gt;

&lt;p&gt;You boot into your favorite Linux distribution, confidently type what you think is your password, and get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Authentication failure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You try again.&lt;/p&gt;

&lt;p&gt;Still wrong.&lt;/p&gt;

&lt;p&gt;A few more attempts later, you realize you've forgotten your password.&lt;/p&gt;

&lt;p&gt;Many people panic at this point, assuming they need to reinstall the operating system. Fortunately, that's rarely necessary.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Password Recovery Is Possible
&lt;/h2&gt;

&lt;p&gt;Linux separates several security concepts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User account passwords&lt;/li&gt;
&lt;li&gt;Root (administrator) privileges&lt;/li&gt;
&lt;li&gt;Physical access to the machine&lt;/li&gt;
&lt;li&gt;Disk encryption&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If someone can boot the operating system and obtain a root shell, they can change any user's password.&lt;/p&gt;

&lt;p&gt;The key insight is that Linux trusts administrators to manage user accounts.&lt;/p&gt;

&lt;p&gt;When you boot into recovery mode, you're effectively entering a maintenance environment where administrative actions are allowed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Recovery Mode on Ubuntu-Based Distributions
&lt;/h2&gt;

&lt;p&gt;On distributions such as Ubuntu, Lubuntu, Kubuntu, Xubuntu, and Linux Mint, the process is straightforward.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Access GRUB
&lt;/h3&gt;

&lt;p&gt;During boot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hold &lt;code&gt;Shift&lt;/code&gt; on BIOS systems&lt;/li&gt;
&lt;li&gt;Press &lt;code&gt;Esc&lt;/code&gt; repeatedly on UEFI systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This should display the GRUB menu.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Enter Recovery Mode
&lt;/h3&gt;

&lt;p&gt;Navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Advanced options for Ubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then select:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(recovery mode)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Open a Root Shell
&lt;/h3&gt;

&lt;p&gt;Choose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root - Drop to root shell prompt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You now have administrative access.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Remount the Filesystem
&lt;/h3&gt;

&lt;p&gt;The root filesystem is usually mounted read-only.&lt;/p&gt;

&lt;p&gt;Remount it as writable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mount &lt;span class="nt"&gt;-o&lt;/span&gt; remount,rw /
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Reset the Password
&lt;/h3&gt;

&lt;p&gt;First, identify the username if necessary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /home
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then change the password:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;passwd username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;passwd john
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter a new password twice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Reboot
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're done.&lt;/p&gt;




&lt;h2&gt;
  
  
  What About Other Linux Distributions?
&lt;/h2&gt;

&lt;p&gt;The same principle applies across most Linux systems.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Distribution&lt;/th&gt;
&lt;th&gt;Typical Recovery Method&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ubuntu Family&lt;/td&gt;
&lt;td&gt;Recovery Mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debian&lt;/td&gt;
&lt;td&gt;Single User Mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fedora&lt;/td&gt;
&lt;td&gt;Emergency Mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arch Linux&lt;/td&gt;
&lt;td&gt;Recovery Shell or Live USB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EndeavourOS&lt;/td&gt;
&lt;td&gt;Same as Arch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;openSUSE&lt;/td&gt;
&lt;td&gt;Rescue Mode&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The interface differs, but the idea remains identical:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Obtain root access&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;passwd&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Set a new password&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The Security Lesson
&lt;/h2&gt;

&lt;p&gt;Many new Linux users assume:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"If someone doesn't know my password, they can't access my computer."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's only partially true.&lt;/p&gt;

&lt;p&gt;If an attacker has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Physical access&lt;/li&gt;
&lt;li&gt;The ability to boot the system&lt;/li&gt;
&lt;li&gt;An unencrypted drive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then they can often reset passwords without knowing the original one.&lt;/p&gt;

&lt;p&gt;This is expected behavior, not a bug.&lt;/p&gt;




&lt;h2&gt;
  
  
  Full-Disk Encryption Changes Everything
&lt;/h2&gt;

&lt;p&gt;Now consider a system protected by LUKS full-disk encryption.&lt;/p&gt;

&lt;p&gt;Before Linux even starts booting, you'll see something similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Please unlock disk...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without the encryption passphrase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recovery mode is inaccessible&lt;/li&gt;
&lt;li&gt;User data remains unreadable&lt;/li&gt;
&lt;li&gt;Password reset procedures become ineffective&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why security professionals often say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your real protection isn't your login password—it's disk encryption.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The login password protects your account.&lt;/p&gt;

&lt;p&gt;Disk encryption protects your data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Linux Allows This
&lt;/h2&gt;

&lt;p&gt;At first glance, being able to reset passwords seems insecure.&lt;/p&gt;

&lt;p&gt;In reality, it solves a practical problem.&lt;/p&gt;

&lt;p&gt;System administrators occasionally forget passwords. Machines become inaccessible. Recovery tools are necessary.&lt;/p&gt;

&lt;p&gt;Linux follows a long-standing philosophy:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Physical access usually implies administrative control.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you want stronger protection against physical attacks, encryption—not account passwords—is the answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Resetting a forgotten Linux password is surprisingly simple across most distributions.&lt;/p&gt;

&lt;p&gt;The process demonstrates an important security principle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Passwords protect accounts.&lt;/li&gt;
&lt;li&gt;Root access controls the system.&lt;/li&gt;
&lt;li&gt;Physical access is powerful.&lt;/li&gt;
&lt;li&gt;Encryption protects data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The next time someone asks, "What happens if I forget my Linux password?" the answer is usually:&lt;/p&gt;

&lt;p&gt;"Boot into recovery mode, reset it, and carry on."&lt;/p&gt;

&lt;p&gt;The more interesting question is:&lt;/p&gt;

&lt;p&gt;"What protects the machine if someone else does the same thing?"&lt;/p&gt;

&lt;p&gt;The answer is full-disk encryption.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>ubuntu</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Apache Hadoop on Ubuntu 22.04 (Beginner-Friendly, Java 8 Without Breaking Java 21)</title>
      <dc:creator>Seamoon Pandey</dc:creator>
      <pubDate>Sat, 31 Jan 2026 14:43:23 +0000</pubDate>
      <link>https://dev.to/seamoonpandey/apache-hadoop-on-ubuntu-2204-beginner-friendly-java-8-without-breaking-java-21-1mb1</link>
      <guid>https://dev.to/seamoonpandey/apache-hadoop-on-ubuntu-2204-beginner-friendly-java-8-without-breaking-java-21-1mb1</guid>
      <description>&lt;p&gt;Hadoop is still a &lt;strong&gt;core concept&lt;/strong&gt; in data engineering — especially for understanding &lt;strong&gt;HDFS, YARN, and distributed systems&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The biggest blocker for beginners today is &lt;strong&gt;Java version conflicts&lt;/strong&gt;.&lt;br&gt;
Most modern systems run &lt;strong&gt;Java 17 or 21&lt;/strong&gt;, while Hadoop prefers &lt;strong&gt;Java 8&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This guide shows you how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install Hadoop &lt;strong&gt;from scratch&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Java 8 only for Hadoop&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Keep your system Java untouched&lt;/li&gt;
&lt;li&gt;Avoid auto-start, battery drain, and common traps&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  What you’ll build
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Hadoop 3.3.6&lt;/li&gt;
&lt;li&gt;Single-node (pseudo-distributed)&lt;/li&gt;
&lt;li&gt;Ubuntu 22.04&lt;/li&gt;
&lt;li&gt;Java 8 for Hadoop only&lt;/li&gt;
&lt;li&gt;Manual start/stop (laptop-friendly)&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu 22.04&lt;/li&gt;
&lt;li&gt;Internet connection&lt;/li&gt;
&lt;li&gt;sudo access&lt;/li&gt;
&lt;li&gt;No prior Hadoop knowledge required&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Step 1: System preparation
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; ssh rsync curl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Hadoop relies on SSH — even on a single machine.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 2: Create a dedicated Hadoop user (recommended)
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;adduser hadoop
&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;hadoop
su - hadoop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;From here on, &lt;strong&gt;everything runs as the &lt;code&gt;hadoop&lt;/code&gt; user&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 3: Enable passwordless SSH
&lt;/h2&gt;

&lt;p&gt;Hadoop services communicate over SSH.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; ~/.ssh/id_rsa.pub &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.ssh/authorized_keys
&lt;span class="nb"&gt;chmod &lt;/span&gt;600 ~/.ssh/authorized_keys
ssh localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it logs in without asking for a password → you’re good.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Java setup (important)
&lt;/h2&gt;

&lt;p&gt;Hadoop works best with &lt;strong&gt;Java 8&lt;/strong&gt;.&lt;br&gt;
You &lt;strong&gt;do NOT&lt;/strong&gt; need to uninstall Java 17/21.&lt;/p&gt;

&lt;p&gt;Verify Java 8 exists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /usr/lib/jvm/java-8-openjdk-amd64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it exists, continue.&lt;br&gt;
(You can install it with &lt;code&gt;sudo apt install openjdk-8-jdk&lt;/code&gt; if missing.)&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 5: Download Hadoop
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
wget https://downloads.apache.org/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xvzf&lt;/span&gt; hadoop-3.3.6.tar.gz
&lt;span class="nb"&gt;mv &lt;/span&gt;hadoop-3.3.6 hadoop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Hadoop environment variables
&lt;/h2&gt;

&lt;p&gt;Edit &lt;code&gt;.bashrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add at the bottom:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HADOOP_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/hadoop
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HADOOP_INSTALL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HADOOP_HOME&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HADOOP_MAPRED_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HADOOP_HOME&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HADOOP_COMMON_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HADOOP_HOME&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HADOOP_HDFS_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HADOOP_HOME&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;YARN_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HADOOP_HOME&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:&lt;span class="nv"&gt;$HADOOP_HOME&lt;/span&gt;/bin:&lt;span class="nv"&gt;$HADOOP_HOME&lt;/span&gt;/sbin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 7: Bind Hadoop to Java 8 (critical step)
&lt;/h2&gt;

&lt;p&gt;This avoids breaking your other Java projects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano ~/hadoop/etc/hadoop/hadoop-env.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;JAVA_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/lib/jvm/java-8-openjdk-amd64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hadoop version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Java version: 1.8.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 8: Hadoop configuration
&lt;/h2&gt;

&lt;p&gt;Move into config directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/hadoop/etc/hadoop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  core-site.xml
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;fs.defaultFS&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;hdfs://localhost:9000&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  hdfs-site.xml
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;dfs.replication&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;dfs.name.dir&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;file:/home/hadoop/hadoopdata/namenode&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;dfs.data.dir&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;file:/home/hadoop/hadoopdata/datanode&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create directories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/hadoopdata/namenode ~/hadoopdata/datanode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  mapred-site.xml
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp &lt;/span&gt;mapred-site.xml.template mapred-site.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;mapreduce.framework.name&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;yarn&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  yarn-site.xml
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;yarn.nodemanager.aux-services&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;mapreduce_shuffle&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 9: Format the NameNode (run ONCE)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hdfs namenode &lt;span class="nt"&gt;-format&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ Running this again wipes HDFS metadata.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 10: Start Hadoop
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;start-dfs.sh
start-yarn.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected processes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NameNode&lt;/li&gt;
&lt;li&gt;DataNode&lt;/li&gt;
&lt;li&gt;SecondaryNameNode&lt;/li&gt;
&lt;li&gt;ResourceManager&lt;/li&gt;
&lt;li&gt;NodeManager&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 11: Access Web UIs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;HDFS: &lt;a href="http://localhost:9870" rel="noopener noreferrer"&gt;http://localhost:9870&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;YARN: &lt;a href="http://localhost:8088" rel="noopener noreferrer"&gt;http://localhost:8088&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If these load → Hadoop is running correctly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 12: Test HDFS
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hdfs dfs &lt;span class="nt"&gt;-mkdir&lt;/span&gt; /test
hdfs dfs &lt;span class="nt"&gt;-put&lt;/span&gt; ~/.bashrc /test
hdfs dfs &lt;span class="nt"&gt;-ls&lt;/span&gt; /test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Found 1 items
-rw-r--r-- 1 hadoop supergroup ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  About the “native-hadoop” warning
&lt;/h2&gt;

&lt;p&gt;You may see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WARN NativeCodeLoader: Unable to load native-hadoop library
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is &lt;strong&gt;normal&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hadoop falls back to pure Java&lt;/li&gt;
&lt;li&gt;No functionality is lost&lt;/li&gt;
&lt;li&gt;Safe to ignore for learning &amp;amp; development&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Does Hadoop auto-start on boot?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;No.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hadoop:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does NOT register as a system service&lt;/li&gt;
&lt;li&gt;Does NOT start after reboot&lt;/li&gt;
&lt;li&gt;Uses &lt;strong&gt;zero resources&lt;/strong&gt; unless manually started&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To stop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;stop-dfs.sh
stop-yarn.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Viola you're done.&lt;/p&gt;

</description>
      <category>hadoop</category>
      <category>java</category>
      <category>programming</category>
    </item>
    <item>
      <title>Transferring SSH Keys (`id_rsa` and `id_rsa.pub`) to a New System</title>
      <dc:creator>Seamoon Pandey</dc:creator>
      <pubDate>Mon, 28 Oct 2024 08:51:54 +0000</pubDate>
      <link>https://dev.to/seamoonpandey/transferring-ssh-keys-idrsa-and-idrsapub-to-a-new-system-4knh</link>
      <guid>https://dev.to/seamoonpandey/transferring-ssh-keys-idrsa-and-idrsapub-to-a-new-system-4knh</guid>
      <description>&lt;p&gt;SSH keys are essential for secure communication between computers. If you're migrating to a new system but want to retain your existing SSH keys (&lt;code&gt;id_rsa&lt;/code&gt; and &lt;code&gt;id_rsa.pub&lt;/code&gt;), follow these steps to seamlessly transfer them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Locate Your SSH Keys
&lt;/h2&gt;

&lt;p&gt;First, identify the location of your SSH keys on your old system. Typically, they reside in the &lt;code&gt;~/.ssh/&lt;/code&gt; directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/.ssh/
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-al&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Backup Your Keys
&lt;/h2&gt;

&lt;p&gt;Ensure the safety of your SSH keys by creating a backup. Copy them to a secure location, such as an encrypted USB drive or a trusted cloud storage service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp &lt;/span&gt;id_rsa id_rsa.pub /path/to/backup/location
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Transfer the Keys to the New System
&lt;/h2&gt;

&lt;p&gt;Use the &lt;code&gt;scp&lt;/code&gt; (secure copy) command to transfer the SSH keys to your new system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp /path/to/backup/location/id_rsa /path/to/backup/location/id_rsa.pub user@new_system_ip:~/.ssh/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;user&lt;/code&gt; with your username on the new system and &lt;code&gt;new_system_ip&lt;/code&gt; with the IP address or hostname of your new system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Set Permissions
&lt;/h2&gt;

&lt;p&gt;Ensure that the permissions of your &lt;code&gt;id_rsa&lt;/code&gt; file are secure. Only the owner should have read and write permissions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;600 ~/.ssh/id_rsa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Add Public Key to Authorized Keys
&lt;/h2&gt;

&lt;p&gt;Append the contents of your &lt;code&gt;id_rsa.pub&lt;/code&gt; file to the &lt;code&gt;authorized_keys&lt;/code&gt; file on your new system. This allows you to authenticate using your SSH private key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; ~/.ssh/id_rsa.pub &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Test the Connection
&lt;/h2&gt;

&lt;p&gt;Finally, test the SSH connection to your new system to ensure everything is set up correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh user@new_system_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If successful, you should log in to your new system without being prompted for a password.&lt;/p&gt;

&lt;p&gt;Congratulations! You've successfully transferred your SSH keys to your new system, ensuring secure access to your remote servers.&lt;/p&gt;




&lt;p&gt;Feel free to customize the instructions further based on your specific environment or requirements!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Reset password mailer implementation in rails 7 api, devise_token_auth, and sendgrid-ruby.</title>
      <dc:creator>Seamoon Pandey</dc:creator>
      <pubDate>Mon, 28 Oct 2024 08:45:37 +0000</pubDate>
      <link>https://dev.to/seamoonpandey/reset-password-mailer-implementation-in-rails-7-api-devisetokenauth-and-sendgrid-ruby-33mg</link>
      <guid>https://dev.to/seamoonpandey/reset-password-mailer-implementation-in-rails-7-api-devisetokenauth-and-sendgrid-ruby-33mg</guid>
      <description>&lt;p&gt;In this guide, we’ll walk through setting up password reset functionality in a Rails app using &lt;code&gt;devise_token_auth&lt;/code&gt; for authentication and SendGrid for email delivery. With this, users can request password reset links sent directly to their emails.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dependencies
&lt;/h2&gt;

&lt;p&gt;Add &lt;code&gt;devise_token_auth&lt;/code&gt; and &lt;code&gt;sendgrid-ruby&lt;/code&gt; to your &lt;code&gt;Gemfile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Sendgrid for sending emails&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'sendgrid-ruby'&lt;/span&gt;

&lt;span class="c1"&gt;# Devise for authentication&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'devise_token_auth'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then install the dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or add each gem individually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle add &lt;span class="s1"&gt;'sendgrid-ruby'&lt;/span&gt;
bundle add &lt;span class="s1"&gt;'devise_token_auth'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;To generate Devise token auth files, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rails g devise_token_auth:install User auth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, open the generated migration file &lt;code&gt;...devise_token_auth_create_users.rb&lt;/code&gt;, and uncomment these lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;   &lt;span class="ss"&gt;:confirmation_token&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;datetime&lt;/span&gt; &lt;span class="ss"&gt;:confirmed_at&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;datetime&lt;/span&gt; &lt;span class="ss"&gt;:confirmation_sent_at&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;   &lt;span class="ss"&gt;:unconfirmed_email&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the migration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bin/rails db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your &lt;code&gt;user.rb&lt;/code&gt; model file, add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;Devise&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Models&lt;/span&gt;
&lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;DeviseTokenAuth&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Concerns&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;User&lt;/span&gt;

&lt;span class="c1"&gt;# Add :recoverable for password recovery&lt;/span&gt;
&lt;span class="n"&gt;devise&lt;/span&gt; &lt;span class="ss"&gt;:database_authenticatable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:registerable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:recoverable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;config/initializers/devise_token_auth.rb&lt;/code&gt;, configure password reset URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;change_headers_on_each_request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;default_password_reset_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'FRONTEND_URL'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/reset-password"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Routes Configuration
&lt;/h2&gt;

&lt;p&gt;In &lt;code&gt;config/routes.rb&lt;/code&gt;, add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;mount_devise_token_auth_for&lt;/span&gt; &lt;span class="s2"&gt;"User"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;at: &lt;/span&gt;&lt;span class="s2"&gt;"auth"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;controllers: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="ss"&gt;passwords: &lt;/span&gt;&lt;span class="s2"&gt;"user/passwords"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Controller Setup
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;controllers/user/passwords_controller.rb&lt;/code&gt; for handling password reset actions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# frozen_string_literal: true&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User::PasswordsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;DeviseTokenAuth&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PasswordsController&lt;/span&gt;
  &lt;span class="c1"&gt;# POST /auth/password&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resource_params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blank?&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;success: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;errors: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Email cannot be blank"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="ss"&gt;status: :unprocessable_entity&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;resource_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_reset_password_instructions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;email: &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;success: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;message: &lt;/span&gt;&lt;span class="s2"&gt;"If the email exists, password reset instructions have been sent."&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="ss"&gt;status: :ok&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# PUT /auth/password&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;password_update_params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:reset_password_token&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;blank?&lt;/span&gt;
      &lt;span class="n"&gt;authenticate_user!&lt;/span&gt;

      &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valid_password?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password_update_params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:old_password&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;success: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;errors: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Old password is incorrect"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="ss"&gt;status: :unprocessable_entity&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;password: &lt;/span&gt;&lt;span class="n"&gt;password_update_params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:password&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;success: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;message: &lt;/span&gt;&lt;span class="s2"&gt;"Password updated successfully for authenticated user"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;success: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;errors: &lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full_messages&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="ss"&gt;status: :unprocessable_entity&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resource_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset_password_by_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password_update_params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;success: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;message: &lt;/span&gt;&lt;span class="s2"&gt;"If the email exists, password reset instructions have been sent."&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;success: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;errors: &lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full_messages&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="ss"&gt;status: :unprocessable_entity&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;password: &lt;/span&gt;&lt;span class="n"&gt;password_update_params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:password&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
      &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;success: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;message: &lt;/span&gt;&lt;span class="s2"&gt;"Password updated successfully"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;StandardError&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;success: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;errors: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"An unexpected error occurred: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="ss"&gt;status: :internal_server_error&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;password_update_params&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;permit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:reset_password_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:password_confirmation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:old_password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;resource_params&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;permit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, users can initiate a password reset by sending a POST request to &lt;code&gt;/auth/password&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Customizing the Email Template
&lt;/h2&gt;

&lt;p&gt;To modify the reset email, update &lt;code&gt;views/devise/mailer/reset_password_instructions.html.erb&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight erb"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Hello &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="vi"&gt;@resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Someone requested a password reset. You can reset it via the link below.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="n"&gt;reset_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DeviseTokenAuth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;default_password_reset_url&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;"?reset_password_token=&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@token&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s1"&gt;'Change my password'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reset_url&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;If you didn’t request this, please ignore this email.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Your password won’t change until you create a new one.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Environment Setup
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Sign in to &lt;a href="https://sendgrid.com/" rel="noopener noreferrer"&gt;SendGrid&lt;/a&gt;, set up your API key, and verify your sender email.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;dotenv&lt;/code&gt; or Rails credentials to securely store the following in your &lt;code&gt;.env&lt;/code&gt; file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SENDGRID_API_KEY=SG.******************
SENDER_EMAIL=your_verified_email@domain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Configure &lt;code&gt;SendGrid&lt;/code&gt; in your environment files (&lt;code&gt;config/environments/development.rb&lt;/code&gt; and &lt;code&gt;config/environments/production.rb&lt;/code&gt;):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;action_mailer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perform_deliveries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;action_mailer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;smtp_settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="ss"&gt;address: &lt;/span&gt;&lt;span class="s2"&gt;"smtp.sendgrid.net"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;port: &lt;/span&gt;&lt;span class="mi"&gt;587&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;authentication: :plain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;user_name: &lt;/span&gt;&lt;span class="s2"&gt;"apikey"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Keep as "apikey"&lt;/span&gt;
  &lt;span class="ss"&gt;password: &lt;/span&gt;&lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"SENDGRID_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="ss"&gt;domain: &lt;/span&gt;&lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"BASE_URL"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="ss"&gt;enable_starttls_auto: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;And that’s it! Now, users can reset their passwords by requesting a link through your Rails API with Devise Token Auth and SendGrid.&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devise-token-auth.gitbook.io/devise-token-auth/config" rel="noopener noreferrer"&gt;Devise Token Auth Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.twilio.com/docs/sendgrid/for-developers/sending-email/rubyonrails" rel="noopener noreferrer"&gt;SendGrid for Rails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/37692756/rails-devise-token-auth-gem-how-do-i-set-password-reset-link" rel="noopener noreferrer"&gt;Devise Password Reset on StackOverflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>sendgrid</category>
      <category>devise</category>
      <category>rails</category>
      <category>forgotpassword</category>
    </item>
    <item>
      <title>Swapping Numbers Without a Temporary Variable in C using XOR like a pro.</title>
      <dc:creator>Seamoon Pandey</dc:creator>
      <pubDate>Thu, 22 Feb 2024 02:48:34 +0000</pubDate>
      <link>https://dev.to/seamoonpandey/swapping-numbers-without-a-temporary-variable-in-c-using-xor-like-a-pro-4jbp</link>
      <guid>https://dev.to/seamoonpandey/swapping-numbers-without-a-temporary-variable-in-c-using-xor-like-a-pro-4jbp</guid>
      <description>&lt;p&gt;Swapping the values of two variables without using a temporary variable is a classic programming problem. One elegant solution to this problem in C involves using bitwise XOR operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Algorithm
&lt;/h2&gt;

&lt;p&gt;Consider two variables &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;. The goal is to swap their values.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Initialize &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; with the values to be swapped.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Perform the following steps:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;^=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;^=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;^=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Explanation
&lt;/h2&gt;

&lt;p&gt;Let's break down the algorithm step by step:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;a ^= b;&lt;/code&gt;: XOR (&lt;code&gt;^=&lt;/code&gt;) &lt;code&gt;a&lt;/code&gt; with &lt;code&gt;b&lt;/code&gt; and store the result back in &lt;code&gt;a&lt;/code&gt;. After this operation, &lt;code&gt;a&lt;/code&gt; contains the result of &lt;code&gt;a XOR b&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;b ^= a;&lt;/code&gt;: XOR &lt;code&gt;b&lt;/code&gt; with the new value of &lt;code&gt;a&lt;/code&gt; (which was the original value of &lt;code&gt;b&lt;/code&gt;). After this operation, &lt;code&gt;b&lt;/code&gt; contains the result of &lt;code&gt;b XOR (a XOR b)&lt;/code&gt;, which simplifies to &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;a ^= b;&lt;/code&gt;: XOR &lt;code&gt;a&lt;/code&gt; with the new value of &lt;code&gt;b&lt;/code&gt; (which was the original value of &lt;code&gt;a&lt;/code&gt;). After this operation, &lt;code&gt;a&lt;/code&gt; contains the result of &lt;code&gt;(a XOR b) XOR a&lt;/code&gt;, which simplifies to &lt;code&gt;b&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, &lt;code&gt;a&lt;/code&gt; holds the original value of &lt;code&gt;b&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; holds the original value of &lt;code&gt;a&lt;/code&gt;, effectively swapping their values without using a temporary variable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;^=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;^=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;^=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>c</category>
      <category>swapping</category>
      <category>swap</category>
    </item>
    <item>
      <title>Ruby on Rails Api authentication with rails cookie session.</title>
      <dc:creator>Seamoon Pandey</dc:creator>
      <pubDate>Sun, 10 Dec 2023 03:55:45 +0000</pubDate>
      <link>https://dev.to/seamoonpandey/ruby-on-rails-api-authentication-with-rails-cookie-session-2jfi</link>
      <guid>https://dev.to/seamoonpandey/ruby-on-rails-api-authentication-with-rails-cookie-session-2jfi</guid>
      <description>&lt;h2&gt;
  
  
  Backend (Rails API)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Create a New Rails API Project
&lt;/h3&gt;

&lt;p&gt;To start building your Rails API, open your terminal and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rails new your_api_project_name &lt;span class="nt"&gt;--api&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; postgresql
&lt;span class="nb"&gt;cd &lt;/span&gt;your_api_project_name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation: This command initializes a new Rails API project, enabling API-only functionality and using PostgreSQL as the database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Integrate Devise and Devise Token Auth
&lt;/h3&gt;

&lt;p&gt;Add Devise and Devise Token Auth to your Gemfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'devise_token_auth'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, execute the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;install
&lt;/span&gt;rails generate devise:install
rails generate devise_token_auth:install
rails db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation: These commands install and configure Devise along with Devise Token Auth. They set up authentication for your User model and create the necessary files and database tables.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Configure ApplicationController
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;app/controllers/application_controller.rb&lt;/code&gt;, add the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApplicationController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;API&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Cookies&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;DeviseTokenAuth&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Concerns&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SetUserByToken&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation: This configures your ApplicationController to include modules for handling cookies and setting the user based on the authentication token.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Configure Application
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;config/application.rb&lt;/code&gt;, add the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api_only&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;session_store&lt;/span&gt; &lt;span class="ss"&gt;:cookie_store&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;key: &lt;/span&gt;&lt;span class="s1"&gt;'_your_api_session'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;httponly: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;same_site: :strict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;secure: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Cookies&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;session_store&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;session_options&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation: These configurations ensure that your API works in an API-only mode, sets up secure cookie storage, and adds necessary middleware.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Configure Devise Token Auth
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;config/initializers/devise_token_auth.rb&lt;/code&gt;, add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cookie_enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cookie_attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="ss"&gt;httponly: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;encrypt: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;same_site: :strict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;secure: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;config/routes.rb&lt;/code&gt;, mount Devise Token Auth for the 'User' model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;mount_devise_token_auth_for&lt;/span&gt; &lt;span class="s1"&gt;'User'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;at: &lt;/span&gt;&lt;span class="s1"&gt;'auth'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation: These configurations enable token authentication and set up cookie attributes for added security.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frontend (Using Axios)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 6: Set Up Axios for Authenticated Requests
&lt;/h3&gt;

&lt;p&gt;Install Axios using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add axios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when making authenticated requests, use Axios with &lt;code&gt;withCredentials: true&lt;/code&gt;:&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="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your/api/endpoint&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="na"&gt;withCredentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle the response&lt;/span&gt;
  &lt;span class="p"&gt;})&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;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle the error&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation: Axios is a popular HTTP client for the browser and Node.js. The &lt;code&gt;withCredentials: true&lt;/code&gt; option ensures that cookies are sent with requests, crucial for authentication.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7: Middleware for Authenticated Requests
&lt;/h3&gt;

&lt;p&gt;Consider creating a middleware for handling authentication in your frontend. Middleware can centralize logic for authenticated requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 8: Manage Authenticated State with a Cookie
&lt;/h3&gt;

&lt;p&gt;Use a &lt;code&gt;logged_in&lt;/code&gt; cookie to manage the authenticated state on the client side. Set it to &lt;code&gt;true&lt;/code&gt; on login and &lt;code&gt;false&lt;/code&gt; on logout or session expiration.&lt;/p&gt;

&lt;p&gt;Explanation: This helps keep track of the user's authentication status on the frontend, providing a seamless user experience.&lt;/p&gt;




&lt;p&gt;This guide covers the setup of a Rails API with token-based authentication using Devise and Devise Token Auth, along with frontend integration using Axios. Feel free to customize these steps based on your project's specific needs. If you have any questions or need further clarification, Mate, do some more research!&lt;/p&gt;

</description>
      <category>rails</category>
      <category>cookie</category>
    </item>
  </channel>
</rss>
