{"id":25074618,"url":"https://github.com/uiu-developers-hub/likhalikhi","last_synced_at":"2026-04-07T07:32:56.405Z","repository":{"id":248541520,"uuid":"828258475","full_name":"UIU-Developers-Hub/likhalikhi","owner":"UIU-Developers-Hub","description":"[Under Development]...This will be a blog application and tech stack will be (MERN) {MongoDb, Express, React JS , Node JS}}","archived":false,"fork":false,"pushed_at":"2024-12-04T17:05:16.000Z","size":1122,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-03T14:23:38.910Z","etag":null,"topics":["expressjs","javascript","jwt-token","mongodb","mongoose","nodejs","reactjs","taliwindcss"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/UIU-Developers-Hub.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-07-13T15:33:46.000Z","updated_at":"2024-12-04T17:05:20.000Z","dependencies_parsed_at":"2024-10-27T20:59:29.657Z","dependency_job_id":"c1a3c40f-9671-4a28-8312-d5ce1e5afaee","html_url":"https://github.com/UIU-Developers-Hub/likhalikhi","commit_stats":null,"previous_names":["uiu-developers-hub/likhalikhi"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/UIU-Developers-Hub/likhalikhi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UIU-Developers-Hub%2Flikhalikhi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UIU-Developers-Hub%2Flikhalikhi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UIU-Developers-Hub%2Flikhalikhi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UIU-Developers-Hub%2Flikhalikhi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/UIU-Developers-Hub","download_url":"https://codeload.github.com/UIU-Developers-Hub/likhalikhi/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UIU-Developers-Hub%2Flikhalikhi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31504896,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T03:10:19.677Z","status":"ssl_error","status_checked_at":"2026-04-07T03:10:13.982Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["expressjs","javascript","jwt-token","mongodb","mongoose","nodejs","reactjs","taliwindcss"],"created_at":"2025-02-07T00:17:59.100Z","updated_at":"2026-04-07T07:32:56.375Z","avatar_url":"https://github.com/UIU-Developers-Hub.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# likhalikhi\n\nWelcome to likhalikhi! This is a blog application project currently under development.\n\n## Contents\n\n- [Tech Stack](#tech-stack)\n- [Current Status](#current-status)\n- [JWT Authentication](#jwt-authentication)\n  - [What is JWT?](#what-is-jwt)\n  - [How a JWT is Structured?](#how-a-jwt-is-structured)\n  - [How to Securely Store JWT on the Client Side?](#how-to-securely-store-jwt-on-the-client-side)\n  - [How to Invalidate a JWT Token](#how-to-invalidate-a-jwt-token)\n  - [JWT vs Session](#jwt-vs-session)\n  - [How JWT Works in likhalikhi](#how-jwt-works-in-likhalikhi)\n  - [JWT Setup](#jwt-setup)\n- [Database Models](#database-models)\n  - [User Model](#user-model)\n  - [Post Model](#post-model)\n\n## Tech Stack\n\n- MongoDB\n- Express.js\n- React.js\n- Node.js\n\n\u003c!-- ## Contributing\n\nWe welcome contributions to likhalikhi! If you're interested in contributing, please follow these steps:\n1. Fork the repository.\n2. Create your feature branch (`git checkout -b feature/YourFeature`).\n3. Commit your changes (`git commit -am 'Add some feature'`).\n4. Push to the branch (`git push origin feature/YourFeature`).\n5. Create a new Pull Request. --\u003e\n\n## Current Status\n\n- Frontend UI in progress.\n- JWT Authentication in progress.\n\n## JWT Authentication\n\n### What is JWT?\n\nJSON Web Token (JWT) is an open standard (RFC 7519) for securely transmitting information between parties as a JSON object. It is commonly used for authentication and information exchange.\n\n### How a JWT structured?\n\nJSON Web Token (JWT) is a long string . which is divided by three parts [header.information.verifyable-singature]. It is a encoded string looks like\n\n```\neyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c\n```\n\nheader, information, verifyable signature are separated by ' . '(dot)\n\n### How do you securely store JWT in client side?\n\nwe can store `JWT` in local-storage, session, and cookies for client side. but in loca-storage is not safe because there could be `js` attack and `js` can easily access localStorage .\nso we can keep JWT in our session or cookies. and also we can add expirery time for JWT.\n\n### How can you invalidate a JWT token\n\nwe can invalidate a JWT token by adding expirary time. There is `refresh token` concept to handle the situation of _if jwt expired and you make a request in server_ .\n\n### JWT vs Session\n\nJWT (JSON Web Token) and sessions are both methods for handling user authentication, but they have some key differences in their design and usage:\n**JWT process:**\n|client|Server|database|\n|------|------|-------|\n|login (username , password)---\u003e||\n||validate user credential ---\u003e|\n|||\u003c--- credential valid|\n||\u003c---issue JWT token||\n|API Request (with JWT token)---\u003e |||\n||Validation Token (Stateless) {`checking in Server`}||\n|`Token Valid\u003c---`|||\n||`\u003c---Fetch/Store Data---\u003e`||\n|`if Token Invalid`|||\n||`\u003c--invalid token response`||\n\n**Session process:**\n|client|Server|database|\n|------|------|-------|\n|login (username , password)---\u003e||\n||validate user credential ---\u003e|\n|||\u003c--- credential valid|\n||\u003c---set Session ID Cookie||\n|API Request (with Session ID)---\u003e |||\n||validate Session ID (Stateful)---\u003e||\n|`Token Valid\u003c---`|||\n||`\u003c---Fetch/Store Data---\u003e`||\n|`if Token Invalid`|||\n||`\u003c--invalid token response`||\n\n**JWT:**\nJWTs are stateless. Once a JWT is issued, the server does not need to store any session data. The JWT itself contains all the information needed for authentication and is verified using a secret key.A JWT contains all the user information needed for authentication (such as user ID, roles, expiration time) within the token itself. This data is encoded as a JSON object and then signed using a secret key or a public/private key pair.\n\n**Session:**\nSessions are stateful. When a user logs in, the server creates a session and stores session data on the server (usually in memory, a database, or a distributed cache). The server sends a session identifier (session ID) to the client, typically stored in a cookie.All session data is stored on the server, and the session ID is used to retrieve the session data on subsequent requests.\n\nChoosing between JWT and sessions depends on the specific requirements of your application, such as scalability, security, and the architecture of your system.\n\n### How JWT Works in likhalikhi\n\n1. **User Registration/Login:**\n\n   - Users register or log in with their credentials.\n   - Upon successful authentication, a JWT is generated and sent to the client.\n\n2. **Token Storage:**\n\n   - The client stores the JWT (typically in localStorage or cookies).\n\n3. **Authenticated Requests:**\n   - The client includes the JWT in the Authorization header for subsequent requests to protected endpoints.\n   - The server validates the JWT and grants access if the token is valid.\n\n### JWT Setup\n\n1. **Dependencies:**\n\n   - Install the necessary packages:\n     ```sh\n     npm install jsonwebtoken bcryptjs\n     ```\n\n2. **User Model:**\n   - Create a User model to handle user data and authentication logic.\n3. **Auth Middleware:**\n\n   - Create middleware to protect routes and validate JWTs.\n\n     ```js\n     const jwt = require(\"jsonwebtoken\");\n\n     const verifyToken = (req, res, next) =\u003e {\n       const token = req.header(\"Authorization\").replace(\"Bearer \", \"\");\n\n       if (!token) return res.status(401).send(\"Access Denied\");\n\n       try {\n         const verified = jwt.verify(token, process.env.JWT_SECRET);\n         req.user = verified;\n         next();\n       } catch (err) {\n         res.status(400).send(\"Invalid Token\");\n       }\n     };\n\n     module.exports = verifyToken;\n     ```\n\n4. **Auth Routes:**\n\n   - Set up routes for user registration and login.\n\n5. **Environment Variables:**\n   - Add a `.env` file with your JWT secret:\n     ```\n     JWT_SECRET=your_jwt_secret\n     ```\n\n## Database Models\n\nAs i am configure my database in `Mongodb` we need `mongoose` for create our models and more easily.\n\n### User model\n\nin this model we add `bcrypt` for hash our password and `jsonwebtoken` for geting access token and refresh token so that we can save it on our cookie or some places. so that we can easily get our necessary information.\n\n```js\nimport bcrypt from \"bcrypt\";\nimport jwt from \"jsonwebtoken\";\nimport mongoose from \"mongoose\";\n\nconst userSchema = new mongoose.Schema(\n  {\n    username: {\n      type: String,\n      required: true,\n      unique: true,\n      lowercase: true,\n      trim: true,\n      index: true,\n      min: [3, \"Username must be at least 3, got {VALUE}\"],\n    },\n    email: {\n      type: String,\n      required: true,\n      unique: true,\n      lowercase: true,\n      trim: true,\n    },\n    username: {\n      type: String,\n      required: true,\n      trim: true,\n      index: true,\n    },\n    password: {\n      type: String,\n      required: [true, \"Password is required\"], //for custom message\n    },\n    avater: {\n      type: String, //Cloudinary URL\n      required: true,\n    },\n    refreshToken: {\n      type: String,\n    },\n  },\n  { timestamps: true }\n);\n\n//this pre is a middleware it works like before the data save/or whatever i do in this schema.\n// we can run a function . there . \"save\" is for ... before save it will call not update or other things\nuserSchema.pre(\"save\", async function (next) {\n  if (!this.isModified(\"password\")) {\n    return next();\n  }\n\n  this.password = bcrypt.hash(this.password, 10);\n  next();\n});\n\n//creating custom method [we named it \"isPasswordCorrect\"]\nuserSchema.methods.isPasswordCorrect = async function (password) {\n  //logic for checking\n  return await bcrypt.compare(password, this.password);\n};\n\nuserSchema.methods.generateAccessToken = function (password) {\n  return jwt.sign(\n    {\n      _id: this._id,\n      email: this.email,\n      username: this.username,\n      fullname: this.fullname,\n    },\n    process.env.ACCESS_TOKEN_SECRET,\n    { expiresIn: process.env.ACCESS_TOKEN_EXPIRY }\n  );\n};\nuserSchema.methods.generateRefreshToken = function (password) {\n  return jwt.sign(\n    {\n      _id: this._id,\n    },\n    process.env.REFRESH_TOKEN_SECRET,\n    { expiresIn: process.env.REFRESH_TOKEN_EXPIRY }\n  );\n};\n\nexport const User = mongoose.model(\"User\", userSchema);\n```\n\n### Post model\n\nin this post model we add `mongoose-aggregate-paginate-v2` to do some advance command operation in mongodb database.\n\n```js\nimport mongoose from \"mongoose\";\nimport mongooseAggregatePaginate from \"mongoose-aggregate-paginate-v2\";\n\nconst postSchema = new mongoose.Schema(\n  {\n    title: {\n      type: String,\n      required: true,\n    },\n    description: {\n      type: String,\n      required: true,\n    },\n    category: {\n      type: String,\n      required: true,\n    },\n    postImage: {\n      type: String, //cloudinary url\n    },\n    isPublished: {\n      type: Boolean,\n      default: true,\n    },\n    createdBy: {\n      //who created this post\n      type: mongoose.Schema.Types.ObjectId,\n      ref: \"User\",\n    },\n  },\n  { timestamps: true }\n);\n\npostSchema.plugin(mongooseAggregatePaginate);\n\nexport const Post = mongoose.model(\"Post\", postSchema);\n```\n\nFeel free to explore the code and reach out if you have any questions or ideas!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuiu-developers-hub%2Flikhalikhi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuiu-developers-hub%2Flikhalikhi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuiu-developers-hub%2Flikhalikhi/lists"}