Pieniä kysymyksiä ohjelmoinnista

Rupesin virittelemään GitHub Actionsia end-to-end-testien ajamiseen. Mulla on siis node backend and React frontend. Teen end-to-end testit Cypress-frameworkilla. Jotta saisin testit toimimaan, täytyy CI-ympäristön suorittaa suunnilleen seuraavat vaiheet:

  1. Asenna node
  2. Käynnistä servu
  3. Asenna cypress
  4. Käynnistä development-servu
  5. Aja cypress-testit

Tässä tämän hetkinen yaml-koodi:

Koodi:
name: End-to-end tests
on: [push, pull_request]
jobs:
  cypress-run:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Use Node.js
        uses: actions/setup-node@v1
      - run: |
          npm install
          npm run start:ci
        working-directory: backend
        env:
          TEST_MONGODB_URI: ${{ secrets.TEST_MONGODB_URI }}
          JWT_SECRET: ${{ secrets.JWT_SECRET }}
          RECAPTCHA_SECRET_TEST: ${{ secrets.RECAPTCHA_SECRET_TEST }}

      - name: Cypress run
        uses: cypress-io/github-action@v1
        with:
          working-directory: frontend
          config-file: frontend/cypress.json
          start: npm run start
          wait-on: http://localhost:3000

Nyt tuo action jää jumiin vaiheeseen 2. Serveri käynnistyy, mutta action jää jumiin siihen vaiheeseen ilman mitään virheilmoitusta. Mun täytyy peruuttaa action manuaalisesti, muuten se jää vaan jumiin määrittelemättömäksi ajaksi (timeout on vissiin 6h). npm start:ci ajaa NODE_ENV=test node server.js -komennon, joka siis vaan käynnistää serverin test-ympäristöön.

Osaako joku sanoa mitä teen väärin?
 
Rupesin virittelemään GitHub Actionsia end-to-end-testien ajamiseen. Mulla on siis node backend and React frontend. Teen end-to-end testit Cypress-frameworkilla. Jotta saisin testit toimimaan, täytyy CI-ympäristön suorittaa suunnilleen seuraavat vaiheet:

  1. Asenna node
  2. Käynnistä servu
  3. Asenna cypress
  4. Käynnistä development-servu
  5. Aja cypress-testit

Tässä tämän hetkinen yaml-koodi:

Koodi:
name: End-to-end tests
on: [push, pull_request]
jobs:
  cypress-run:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Use Node.js
        uses: actions/setup-node@v1
      - run: |
          npm install
          npm run start:ci
        working-directory: backend
        env:
          TEST_MONGODB_URI: ${{ secrets.TEST_MONGODB_URI }}
          JWT_SECRET: ${{ secrets.JWT_SECRET }}
          RECAPTCHA_SECRET_TEST: ${{ secrets.RECAPTCHA_SECRET_TEST }}

      - name: Cypress run
        uses: cypress-io/github-action@v1
        with:
          working-directory: frontend
          config-file: frontend/cypress.json
          start: npm run start
          wait-on: http://localhost:3000

Nyt tuo action jää jumiin vaiheeseen 2. Serveri käynnistyy, mutta action jää jumiin siihen vaiheeseen ilman mitään virheilmoitusta. Mun täytyy peruuttaa action manuaalisesti, muuten se jää vaan jumiin määrittelemättömäksi ajaksi (timeout on vissiin 6h). npm start:ci ajaa NODE_ENV=test node server.js -komennon, joka siis vaan käynnistää serverin test-ympäristöön.

Osaako joku sanoa mitä teen väärin?
Olisko tämä:
We are getting reports that Cypress has suddenly started crashing when running on ubuntu-latest OS. Seems, GH Actions have switched from 16.04 to 18.04 overnight, and are having a xvfb issue. Please work around this problem by using runs-on: ubuntu-16.04 image or upgrading to Cypress v3.8.3 where we explicitly set XVFB arguments.
 
Olisko tämä:
We are getting reports that Cypress has suddenly started crashing when running on ubuntu-latest OS. Seems, GH Actions have switched from 16.04 to 18.04 overnight, and are having a xvfb issue. Please work around this problem by using runs-on: ubuntu-16.04 image or upgrading to Cypress v3.8.3 where we explicitly set XVFB arguments.
Ei ollut tuo. Sain tuon kuitenki toimimaan näin:

Koodi:
name: End-to-end tests
on: [push, pull_request]
jobs:
  cypress-run:
    runs-on: ubuntu-16.04
    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Use Node.js
        uses: actions/setup-node@v1
        with:
          node-version: 12
      - run: npm install
        working-directory: backend
      - name: Cypress run
        uses: cypress-io/github-action@v1
        with:
          working-directory: frontend
          config-file: cypress.json
          start: npm run start:ci
          wait-on: http://localhost:3000
        env:
          TEST_MONGODB_URI: ${{ secrets.TEST_MONGODB_URI }}
          JWT_SECRET: ${{ secrets.JWT_SECRET }}
          RECAPTCHA_SECRET_TEST: ${{ secrets.RECAPTCHA_SECRET_TEST }}

Eli nyt tein tonne frontendin puolelle package.json tiedostoon start:ci skriptin, joka käynnistää backendin ja frontendin näin: "start:ci": "cd ../backend && npm run start:ci & npm start".

Nyt testit pyörähti käyntiin oikein ja suurin osa meni jopa läpi. Jotkut testit feilasi, mutta ainoastaan käyttöjärjestelmäerojen takia.
 
Tee funktio nimeltä tutkiKumpiOnSuurempiLuku(). Funktio saa parametrina (parameters) kaksi kokonaislukua ja palauttaa (return) niistä suuremman.

Tee myös funktion kutsu (call).


Tuommoinen pitäisi väsätä, ikinä tehny funktioita. Joten jos vinkkejä tästä joku voisi antaa.
 
Tee funktio nimeltä tutkiKumpiOnSuurempiLuku(). Funktio saa parametrina (parameters) kaksi kokonaislukua ja palauttaa (return) niistä suuremman.

Tee myös funktion kutsu (call).


Tuommoinen pitäisi väsätä, ikinä tehny funktioita. Joten jos vinkkejä tästä joku voisi antaa.
Oletan, että kieli on edelleen JavaScript: JavaScript Functions
Tuolta kun maltat lukea pari esimerkkiä niin sinulle selviää mikä on funktio ja miten sitä (tai niitä) käytetään.
 
 
Tuon alkuperäisen tehtävän anto (sekä esimerkki ovat sen verran nihkeät) sekä noiden parin Java-sivuston ohjeet/vinkit auttaa mutta kun ei oo mitään kokemusta niin hankala keksiä tuurilla miten muodostaa funktio oikein.
Ohjesivustoja on miljoonia mutta yhdeltäkään en oo löytänyt semmosta ihan alkajille helppoa lähestymistä. JavaScript Functions on hyvä mutta siellä voisi olla enemmänkin vielä esimerkkejä noista.
No pitää yrittää kokeilla jospa tuosta jotain saisi toimimaan vielä.
 
Tuon alkuperäisen tehtävän anto (sekä esimerkki ovat sen verran nihkeät) sekä noiden parin Java-sivuston ohjeet/vinkit auttaa mutta kun ei oo mitään kokemusta niin hankala keksiä tuurilla miten muodostaa funktio oikein.
Ohjesivustoja on miljoonia mutta yhdeltäkään en oo löytänyt semmosta ihan alkajille helppoa lähestymistä. JavaScript Functions on hyvä mutta siellä voisi olla enemmänkin vielä esimerkkejä noista.
No pitää yrittää kokeilla jospa tuosta jotain saisi toimimaan vielä.
Koodi:
//functio
function tutkiKumpiOnSuurempiLuku(luku1, luku2){
    if(luku1 > luku 2){
        return luku1;
    }
    if(luku1 < luku2){
        return luku2
    }
}

//Esitellään muuttujat
var luku1 = 1;
var luku2 = 2;
//Kutsutaan funktiota
tutkiKumpiOnSuurempiLuku(luku1, luku2);
 
Mikähän mahtaa olla turvallinen tapa säilöä JWT -token frontissa? Tällä hetkellä se säilötään local storagessa ja tiedän, ettei se ole paras tapa.

Kyseessä React + Node.js kombo.

edit: Muotoillaan uusiksi. Mikä on turvallinen tapa käyttää Json Web Tokenia?
 
Viimeksi muokattu:
Tuon alkuperäisen tehtävän anto (sekä esimerkki ovat sen verran nihkeät) sekä noiden parin Java-sivuston ohjeet/vinkit auttaa mutta kun ei oo mitään kokemusta niin hankala keksiä tuurilla miten muodostaa funktio oikein...
Itse käsitin tuon tehtävänannon, että pitäisi antaa yhtenä parametrina, eli objektina. En tosin tiedä, mitkä niiden avaimien nimet olisivat ja miksi näin pitäisi tehdä? En myöskään ymmärtänyt, että mihin väliin se `.call()` pitäisi upottaa, tai mikä on se use case.

Joka tapauksessa omalla kohdalla tekisin jotain tällaista. Kysy tarvittaessa, jos jokin kohta ihmetyttää:
JavaScript:
const tutkiKumpiOnSuurempi = (a = 0, b = 0) => ((a >= b) ? a : b);

Eli laittaisin oletusarvot (0) molemmille muuttujille ihan siitä syystä, että tällöin ei tarvitse tehdä (yhtä monimutkaista) virheenkäsittelyä (jos funktiota kutsutaan jostain syystä esim. undefined arvolla). Tämä myös "kommunikoi", että parametrien on tarkoitus olla numeroita.

Mutta tässä tapauksessa avainsanoina ainakin javascript const, fat arrow functions, ternary operators ja ehkä myös implicit return.
 
Viimeksi muokattu:
Joka tapauksessa omalla kohdalla tekisin jotain tällaista. Kysy tarvittaessa, jos jokin kohta ihmetyttää:
JavaScript:
const tutkiKumpiOnSuurempi = (a = 0, b = 0) => ((a >= b) ? a : b));
Onks tossa yks sulku liikaa. Ihan hölmö tehtävä muutenkin kun on jo
JavaScript:
Math.max(1,2);
 
Mikähän mahtaa olla turvallinen tapa säilöä JWT -token frontissa? Tällä hetkellä se säilötään local storagessa ja tiedän, ettei se ole paras tapa.

Kyseessä React + Node.js kombo.

edit: Muotoillaan uusiksi. Mikä on turvallinen tapa käyttää Json Web Tokenia?
Millälailla turvallinen? Kaikki data frontissa on käyttäjän luettavissa ja muokattavissa helposti. JWT:n turvallisuushan perustuu allekirjoitukseen, jotta serveripäässä voidaan luottaa ettei tokenia ole muokattu.
 
Onks tossa yks sulku liikaa. Ihan hölmö tehtävä muutenkin kun on jo
JavaScript:
Math.max(1,2);
Hmm... olen varma, että poistin sen kun aluksi tosiaan tuli yksi sulku liikaa. Mutta näköjään jäänyt tuohon, teen ninja-editin.

Mutta mietin itsekin tuota valmista `Math.max()`:ia, mutta ehkä kyse on tosiaan yksinkertaisesti harjoituksesta
 
Koodi:
//functio
function tutkiKumpiOnSuurempiLuku(luku1, luku2){
    if(luku1 > luku 2){
        return luku1;
    }
    if(luku1 < luku2){
        return luku2
    }
}

//Esitellään muuttujat
var luku1 = 1;
var luku2 = 2;
//Kutsutaan funktiota
tutkiKumpiOnSuurempiLuku(luku1, luku2);

Pitäskö tuosta lopuksi tulla ruutuun joku alert?
 
Mikähän mahtaa olla turvallinen tapa säilöä JWT -token frontissa? Tällä hetkellä se säilötään local storagessa ja tiedän, ettei se ole paras tapa.

Kyseessä React + Node.js kombo.

edit: Muotoillaan uusiksi. Mikä on turvallinen tapa käyttää Json Web Tokenia?
Turvallisin paikka on ihan vaan muistissa lyhyellä voimassaoloajalla ja sitten refreshaat sitä. Täällä esim. aika hyvää settiä: The Ultimate Guide to handling JWTs on frontend clients (GraphQL)
 
Millälailla turvallinen? Kaikki data frontissa on käyttäjän luettavissa ja muokattavissa helposti. JWT:n turvallisuushan perustuu allekirjoitukseen, jotta serveripäässä voidaan luottaa ettei tokenia ole muokattu.

Jos joku saa käsiinsä tuon tokenin joka on tallennettu local storageen, niin sillä pystyy tekemään kyselyitä rajapintaan.

Turvallisin paikka on ihan vaan muistissa lyhyellä voimassaoloajalla ja sitten refreshaat sitä. Täällä esim. aika hyvää settiä: The Ultimate Guide to handling JWTs on frontend clients (GraphQL)

Täytyy tutustua tähän.
 
Viimeksi muokattu:
Mikähän mahtaa olla turvallinen tapa säilöä JWT -token frontissa? Tällä hetkellä se säilötään local storagessa ja tiedän, ettei se ole paras tapa.

Kyseessä React + Node.js kombo.

edit: Muotoillaan uusiksi. Mikä on turvallinen tapa käyttää Json Web Tokenia?


JWT oikea paikka on httpOnly cookie.

Millälailla turvallinen? Kaikki data frontissa on käyttäjän luettavissa ja muokattavissa helposti. JWT:n turvallisuushan perustuu allekirjoitukseen, jotta serveripäässä voidaan luottaa ettei tokenia ole muokattu.

Vaikka sillä tavalla, että local ja session storeen pääsee käsiksi millä tahansa koodin pätkällä mitä sivulla ajetaan. Joten XSS tilanteessa tokeni on käytännössä alttarilla odottamassa ottajaansa.
 
Koodi:
//functio
function tutkiKumpiOnSuurempiLuku(luku1, luku2){
    if(luku1 > luku 2){
        return luku1;
    }
    if(luku1 < luku2){
        return luku2
    }
}

//Esitellään muuttujat
var luku1 = 1;
var luku2 = 2;
//Kutsutaan funktiota
tutkiKumpiOnSuurempiLuku(luku1, luku2);



Tämmösellä ainakin eilen toimi mutta nyt heittää hassuja lukuja, kun laittaa vaikka 2 ja 1000 niin väittää että 2 on isompi.
<script>
//Ohjelma ilmoittaa kahdesta käyttäjän antamasta luvusta suuremman

let luku1 = prompt("Anna ensimmäinen luku","0");
let luku2 = prompt("Anna toinen luku","0");

//Kutsutaan funktio
alert(tutkiKumpiOnSuurempiLuku(luku1, luku2));


//functio
function tutkiKumpiOnSuurempiLuku(luku1, luku2){
if(luku1 > luku2){
return luku1;
}
if(luku1 < luku2){
return luku2
}

//Esitellään muuttujat
var luku1 = 1;
var luku2 = 2;

}

</script>

Olisko vinkkejä mikä väärin tai mikä aiheuttaa tuon virheellisen jutun?
 
Viimeksi muokattu:
Tämmösellä ainakin eilen toimi mutta nyt heittää hassuja lukuja, kun laittaa vaikka 2 ja 1000 niin väittää että 2 on isompi.
<script>
//Ohjelma ilmoittaa kahdesta käyttäjän antamasta luvusta suuremman

let luku1 = prompt("Anna ensimmäinen luku","0");
let luku2 = prompt("Anna toinen luku","0");

//Kutsutaan funktio
alert(tutkiKumpiOnSuurempiLuku(luku1, luku2));


//functio
function tutkiKumpiOnSuurempiLuku(luku1, luku2){
if(luku1 > luku2){
return luku1;
}
if(luku1 < luku2){
return luku2
}

//Esitellään muuttujat
var luku1 = 1;
var luku2 = 2;

}

</script>


prompt vastaus on aina stringi.. Eli '2' tekstinä tosiaan on suurempi kuin '1000'


let luku2 = Number(prompt("Anna toinen luku","0")) voit muuttaa syötteen numeroksi jos se on vaihmahdollista..

esim Number('2') === 2 ja Number('string') = NaN
 
Tämmösellä ainakin eilen toimi mutta nyt heittää hassuja lukuja, kun laittaa vaikka 2 ja 1000 niin väittää että 2 on isompi.
<script>
//Ohjelma ilmoittaa kahdesta käyttäjän antamasta luvusta suuremman

let luku1 = prompt("Anna ensimmäinen luku","0");
let luku2 = prompt("Anna toinen luku","0");

//Kutsutaan funktio
alert(tutkiKumpiOnSuurempiLuku(luku1, luku2));


//functio
function tutkiKumpiOnSuurempiLuku(luku1, luku2){
if(luku1 > luku2){
return luku1;
}
if(luku1 < luku2){
return luku2
}

//Esitellään muuttujat
var luku1 = 1;
var luku2 = 2;

}

</script>

Olisko vinkkejä mikä väärin tai mikä aiheuttaa tuon virheellisen jutun?
Muuta luvut integeriksi ennen vertailua.

Koodi:
//Ohjelma ilmoittaa kahdesta käyttäjän antamasta luvusta suuremman

var luku1 = prompt("Anna ensimmäinen luku",0);
var luku2 = prompt("Anna toinen luku",0);
var a = parseInt(luku1);
var b = parseInt(luku2);

//Kutsutaan funktio
alert(tutkiKumpiOnSuurempiLuku(a, b));


//functio
function tutkiKumpiOnSuurempiLuku(luku1, luku2){
    if(luku1 > luku2){
        return luku1;
    }
    if(luku1 < luku2){
        return luku2
    }
}

Edit. naku oli nopeampi
 
Jees, kiitokset avusta ja korjauksesta @Hessu @nnaku nyt toimii.
Tein eilen pari muutakin funktiota ja näyttäs pikkuhiljaa tämäkin avautuvan.
No mutta, pitää muistaa että harjoituksia vaan lisää niin oppii ja virheiden kautta etenkin.
 
Jees, kiitokset avusta ja korjauksesta @Hessu @nnaku nyt toimii.
Tein eilen pari muutakin funktiota ja näyttäs pikkuhiljaa tämäkin avautuvan.
No mutta, pitää muistaa että harjoituksia vaan lisää niin oppii ja virheiden kautta etenkin.
Nuo jutut ovat alkuun kompastuskivinä jonkun aikaa ja ennen kuin vuoden - kaksi opettelee niin aika paljon näihin pieniin asioihin juuttuu kiinni. Googlesta löytyy paljon vastauksia, kun osaa hakea oikeilla hakusanoilla. Alkuun siis stackoverflow yms. ovat ihan hyviä apusivuja.
 
Mikähän on, kun vapaa-ajan React+Node projektissa ei toimi custom-fontti enää production buildissa?

Fontti on kansiossa src/fonts/SuperLegend.ttf

App.css:
Koodi:
@font-face { 
  font-family: 'SuperLegend';
  font-display: fallback;
  src: local('SuperLegend'), 
    url('./fonts/SuperLegendBoy-4w8Y.ttf') format('truetype');
} 

.jokuClass {
  font-family: 'SuperLegend', Helvetica, sans-serif;
}

Jos ajan fronttia react-scripts start, fontti näkyy kuten pitääkin. Tämän jälkeen ajan buildin, ja katson että buildissa fontti on mukana kansiossa /static/media/SuperLegendBoy-4w8Y.18828ef8.ttf. Siirrän buildin backendin alle, ja Node-express -applikaatiossa on app.use('', express.static('build')).

Nyt kun menen backendin tarjoamaan sivuun, tuota fonttia käyttävä teksti puuttuu sivulta täysin. Ei edes fallbackaa muuhun fonttiin. Console-logiin ei tule virheitä. Jos kuitenkin poistan build-kansiosta fontin, saan heti Failed to load resource 404 virheen consoleen, mutta teksti ei silti fallbackaa.

Mitähän minulta puuttuu, että saisin tuon a) fallbackaamaan muuhun fonttiin jos puuttuu ja b) käyttämään custom-fonttia?

Ratkaistu, ks. pari viestiä alempaa.
 
Viimeksi muokattu:
Mikähän on, kun vapaa-ajan React+Node projektissa ei toimi custom-fontti enää production buildissa?

Fontti on kansiossa src/fonts/SuperLegend.ttf

App.css:
Koodi:
@font-face { 
  font-family: 'SuperLegend';
  font-display: fallback;
  src: local('SuperLegend'), 
    url('./fonts/SuperLegendBoy-4w8Y.ttf') format('truetype');
} 

.jokuClass {
  font-family: 'SuperLegend', Helvetica, sans-serif;
}

Jos ajan fronttia react-scripts start, fontti näkyy kuten pitääkin. Tämän jälkeen ajan buildin, ja katson että buildissa fontti on mukana kansiossa /static/media/SuperLegendBoy-4w8Y.18828ef8.ttf. Siirrän buildin backendin alle, ja Node-express -applikaatiossa on app.use('', express.static('build')).

Nyt kun menen backendin tarjoamaan sivuun, tuota fonttia käyttävä teksti puuttuu sivulta täysin. Ei edes fallbackaa muuhun fonttiin. Console-logiin ei tule virheitä. Jos kuitenkin poistan build-kansiosta fontin, saan heti Failed to load resource 404 virheen consoleen, mutta teksti ei silti fallbackaa.

Mitähän minulta puuttuu, että saisin tuon a) fallbackaamaan muuhun fonttiin jos puuttuu ja b) käyttämään custom-fonttia?

Mitäs selaimen devtools -> network sanoo fontin lataamisesta?
 
Mitäs selaimen devtools -> network sanoo fontin lataamisesta?

200 OK.

...ja löysinkin juuri ongelman. Tuo teksti on elementissä, jolle olen merkinnyt opacity: 95%. Jostain syystä buildin aikana tämä vääntyy muotoon opacity: 0.01, joten tekstiä ei vain näy.
Kun kävin sörkkimässä opacity.css:n pois ja font-display: swap; , niin fontti alkoi toimia. Sitten vain ihmettelemään, miksi buildi muuttaa opacity: 95% -> opacity: 1%. :confused:

Ja tällekin löytyi syy: CSS - "opacity" percentage values are bundled incorrectly. · Issue #7980 · facebook/create-react-app
 
Nuo jutut ovat alkuun kompastuskivinä jonkun aikaa ja ennen kuin vuoden - kaksi opettelee niin aika paljon näihin pieniin asioihin juuttuu kiinni. Googlesta löytyy paljon vastauksia, kun osaa hakea oikeilla hakusanoilla. Alkuun siis stackoverflow yms. ovat ihan hyviä apusivuja.

Nimenomaan ja kenties kynnystä nostaa sekin että saa olla tarkkana. Yksikin väärä tai puuttuva merkki tekee sen ettei toimikaan toivotulla tavalla.
 
Yksikin väärä tai puuttuva merkki tekee sen ettei toimikaan toivotulla tavalla.

Tästä ei pääse koskaan eroon. Vieläkin tulee mielenkiintoisia juttuja vastaan kun jättää yhdet sulkeet tai välimerkin pois vaikka koodastusten aloituksesta taitaa olla jo yli 30v.
Scala on osoittautunut tässä pelissä voittajaksi ;)
 
Nimenomaan ja kenties kynnystä nostaa sekin että saa olla tarkkana. Yksikin väärä tai puuttuva merkki tekee sen ettei toimikaan toivotulla tavalla.
Tähän tottuu, kun enemmän koodaa varsinkin, kun alat ymmärtämään debuggerin ja konsolin oksennusta vähän paremmin.

200 OK.

...ja löysinkin juuri ongelman. Tuo teksti on elementissä, jolle olen merkinnyt opacity: 95%. Jostain syystä buildin aikana tämä vääntyy muotoon opacity: 0.01, joten tekstiä ei vain näy.
Kun kävin sörkkimässä opacity.css:n pois ja font-display: swap; , niin fontti alkoi toimia. Sitten vain ihmettelemään, miksi buildi muuttaa opacity: 95% -> opacity: 1%. :confused:

Ja tällekin löytyi syy: CSS - "opacity" percentage values are bundled incorrectly. · Issue #7980 · facebook/create-react-app
Veikkaisin, että tuo fontti imaisee tuon tyylin jostain sen jälkeen, kun tuo määrittämäsi opacity on ladattu. Jos selaimen style -välilehdeltä vaihdat tuon 0.01 -> 95% niin muuttuuko oikeaksi?
 
Yksikin väärä tai puuttuva merkki tekee sen ettei toimikaan toivotulla tavalla.
Tuota tosiaan sattuu pidempäänkin koodanneelle ajoittain mutta tuossa auttaa ainakin itseäni paljon editori jossa on syntax highlight, sulkujen mätsäys sun muut vastaavat apuvälineet. Itse en ole ammattikoodari ja editorina tulee pääsääntöisesti käytettyä vim:iä.
 
Vielä tuosta JWT - autentikoinnista..

Kuljetetaanko tuota JWT Refresh Tokenia siis httpOnly keksissä ja tuo Access Token lykätään fronttiin?
Onko tietokanta pakollinen tässä?

Seurasin tuota The Ultimate Guide to handling JWTs on frontend clients (GraphQL), mutta jossain kohdin meni pää solmuun.
Toi on kyllä monimutkainen esimerkki joka perustuu mikroarkkitehtuuriin. Ymmärsit ihan oikein ja tosiaan vaatii tietokannan. Esim. redis tai joku muu no-sql käy hyvin. @nnaku taisi olla sitä mieltä että token suoraan vaan ilman refreshtoimintoa httpOnly keksiin, joka toteutuksena yksinkertaisempi. Tässä omat tietoturvariskinsä, mutta varmasti parempi kuin localstoressa.

Suosittelen myös tutustumaan firebaseen: Firebase Authentication

Tuotantokelpoinen autentikaatiosysteemi ja sessionhallinta ei ole triviaali asia jos siitä haluaa tietoturvallisen. Hackernoonissa myös hyvä pari osainen juttu aiheesta: All you need to know about user session security
 
Viimeksi muokattu:
Vielä tuosta JWT - autentikoinnista..

Kuljetetaanko tuota JWT Refresh Tokenia siis httpOnly keksissä ja tuo Access Token lykätään fronttiin?
Onko tietokanta pakollinen tässä?

Seurasin tuota The Ultimate Guide to handling JWTs on frontend clients (GraphQL), mutta jossain kohdin meni pää solmuun.

Toi on kyllä monimutkainen esimerkki joka perustuu mikroarkkitehtuuriin. Ymmärsit ihan oikein ja tosiaan vaatii tietokannan. Esim. redis tai joku muu no-sql käy hyvin. @nnaku taisi olla sitä mieltä että token suoraan vaan ilman refreshtoimintoa httpOnly keksiin, joka toteutuksena yksinkertaisempi. Tässä omat tietoturvariskinsä, mutta varmasti parempi kuin localstoressa.

Suosittelen myös tutustumaan firebaseen: Firebase Authentication


Joo siis nimenomaan se "longlived" token olisi kiva saada piiloon. Kunnon JWT implementaatiossa tulisi tosiaan olla Access (shortlived) ja Refresh (longlived) tokenit. Joista sitten Access tokenia voidaan käsitellä "hieman" höllemmin esim tallentamalla se sovelluksen muistiin.
Voin myös suositella valmiita toteutuksia kuten @©©© mainitsema Firebase Auth tai auth0.com, jos ei propellihattuilu kiinnosta. Omasta mielestä JWT implementoinnin askartelu scratchistä on kyllä kohtuu mahdoton tehtävä tehdä kerralla ja oikein.
 
Toi on kyllä monimutkainen esimerkki joka perustuu mikroarkkitehtuuriin. Ymmärsit ihan oikein ja tosiaan vaatii tietokannan. Esim. redis tai joku muu no-sql käy hyvin. @nnaku taisi olla sitä mieltä että token suoraan vaan ilman refreshtoimintoa httpOnly keksiin, joka toteutuksena yksinkertaisempi. Tässä omat tietoturvariskinsä, mutta varmasti parempi kuin localstoressa.

Suosittelen myös tutustumaan firebaseen: Firebase Authentication

Tuotantokelpoinen autentikaatiosysteemi ja sessionhallinta ei ole triviaali asia jos siitä haluaa tietoturvallisen. Hackernoonissa myös hyvä pari osainen juttu aiheesta: All you need to know about user session security
Joo siis nimenomaan se "longlived" token olisi kiva saada piiloon. Kunnon JWT implementaatiossa tulisi tosiaan olla Access (shortlived) ja Refresh (longlived) tokenit. Joista sitten Access tokenia voidaan käsitellä "hieman" höllemmin esim tallentamalla se sovelluksen muistiin.
Voin myös suositella valmiita toteutuksia kuten @©©© mainitsema Firebase Auth tai auth0.com, jos ei propellihattuilu kiinnosta. Omasta mielestä JWT implementoinnin askartelu scratchistä on kyllä kohtuu mahdoton tehtävä tehdä kerralla ja oikein.

Mikähän mahtaisi olla yksinkertaisin toimiva systeemi, jos mennään pelkällä Access Tokenilla?
Access token muistiin sekä httpOnly keksiin, mutta poistanko uloskirjautuessa pelkän keksin?

Tuollainen valmis toteutus olisi hieno, mutta tässä tapauksessa käyttäjät luodaan manuaalisestin.
 
Mikähän mahtaisi olla yksinkertaisin toimiva systeemi, jos mennään pelkällä Access Tokenilla?
Access token muistiin sekä httpOnly keksiin, mutta poistanko uloskirjautuessa pelkän keksin?

Tuollainen valmis toteutus olisi hieno, mutta tässä tapauksessa käyttäjät luodaan manuaalisestin.
Lähtökohtaisesti pelkkä pitkäikäinen access token on kyllä aika huono idea ja JWT:tä ei ole suunniteltu siihen. Eikä se toteutuskaan ole yksinkertainen vaikka sen siten tekisikin, koska uloskirjautuminen tarkoittaa blacklist tietokannan (varmaan taas redis on paras) luomista jonne pistät sen JWT tokenin millä "kirjaudut ulos". Muista että kerran luotu pitkäikäinen JWT on voimassa ja validi koko sen eliniän ajan huolimatta siitä kuka sitä käyttää eikä ilman tietokantaa sitä voi mitenkään invalidoida. Tässä hieman lukemista logout-toiminnallisuudesta:
Täällä taas auth0 blogi refresh tokeneista: Refresh Tokens: When to Use Them and How They Interact with JWTs

Eli kyllä melkein menisin refresh tokenilla jos kerran JWT-toteutuksen meinaat tehdä.

Kuulostaa vähän siltä että HTTP Sessions olisi tässä tapauksessa parempi vaihtoehto JWT:lle? Esim. käyttämällä expressjs/session

Toinen vaihtoehto tosiaan on autentikaatiopalvelun käyttämistä. Esim. Firebase Authenticationissa pystyy myös manuaalisesti (eli admin luo käyttäjät suoraan firebaseen ilman rekisteröitymistä) tekemään käyttäjiä.

Firebase Authentication aims to make building secure authentication systems easy, while improving the sign-in and onboarding experience for end users. It provides an end-to-end identity solution, supporting email and password accounts, phone auth, and Google, Twitter, Facebook, and GitHub login, and more.
 
Viimeksi muokattu:
Mikähän mahtaisi olla yksinkertaisin toimiva systeemi, jos mennään pelkällä Access Tokenilla?
Access token muistiin sekä httpOnly keksiin, mutta poistanko uloskirjautuessa pelkän keksin?

Tuollainen valmis toteutus olisi hieno, mutta tässä tapauksessa käyttäjät luodaan manuaalisestin.


Raotas pikkasen enemmän tätä usecasea ja mitä tarkoitat "käyttäjät luodaan manuaalisestin"?
 
Lähtökohtaisesti pelkkä pitkäikäinen access token on kyllä aika huono idea ja JWT:tä ei ole suunniteltu siihen. Eikä se toteutuskaan ole yksinkertainen vaikka sen siten tekisikin, koska uloskirjautuminen tarkoittaa blacklist tietokannan (varmaan taas redis on paras) luomista jonne pistät sen JWT tokenin millä "kirjaudut ulos". Muista että kerran luotu pitkäikäinen JWT on voimassa ja validi koko sen eliniän ajan huolimatta siitä kuka sitä käyttää eikä ilman tietokantaa sitä voi mitenkään invalidoida. Tässä hieman lukemista logout-toiminnallisuudesta:
Täällä taas auth0 blogi refresh tokeneista: Refresh Tokens: When to Use Them and How They Interact with JWTs

Eli kyllä melkein menisin refresh tokenilla jos kerran JWT-toteutuksen meinaat tehdä.

Kuulostaa vähän siltä että HTTP Sessions olisi tässä tapauksessa parempi vaihtoehto JWT:lle? Esim. käyttämällä expressjs/session

Toinen vaihtoehto tosiaan on autentikaatiopalvelun käyttämistä. Esim. Firebase Authenticationissa pystyy myös manuaalisesti (eli admin luo käyttäjät suoraan firebaseen ilman rekisteröitymistä) tekemään käyttäjiä.

Ehkä JWT ei sovellu mun käyttötarkoitukseen. Täytyy tutustua nähin.

Raotas pikkasen enemmän tätä usecasea ja mitä tarkoitat "käyttäjät luodaan manuaalisestin"?

Tarvin vain muutaman käyttäjän tähän ja ne luodaan siis "manuaalisestin". Käyttäjän ei ole mahdollista itse luoda tunnuksia.

Mutta kiitoksia molemmille, täytyy perehtyä hieman paremmin koko aiheeseen.
 
Ehkä JWT ei sovellu mun käyttötarkoitukseen. Täytyy tutustua nähin.

Tarvin vain muutaman käyttäjän tähän ja ne luodaan siis "manuaalisestin". Käyttäjän ei ole mahdollista itse luoda tunnuksia.

Mutta kiitoksia molemmille, täytyy perehtyä hieman paremmin koko aiheeseen.

Yksi helppo ja karvalakkimallinen JWT-toteutus olisi tehdä siten, että pidät tokenia voimassa yhden päivän eli vaikka 12 tuntia. Pistät JWT:n httpOnly keksiin, ei blacklist-tietokantaa tai refreshiä ja logout-rutiini poistaa keksin käyttäjän selaimesta. Tässä mallissa miinuksena se että käyttäjät joutuvat kirjautumaan uudestaan palveluun joka 12 tunti kun token vanhenee, vaikka eivät olisi kirjautuneet ulos ja käyttäisivät aktiivisesti palvelua. Päivittäin palvelua käyttävät käyttäjät joutuvat siten kirjautumaan joka päivä uudestaan palveluun.

Kun käyttäjä on manuaalisesti kirjautunut ulos niin tietty se JWT on edelleen validi itsessään ja jos joku on sen tokenin sattunut saamaan, on se validi palvelimelle. Käyttäjän pitää kirjautua uudestaan uloskirjatumisen jälkeen, koska hänen selaimessaan ei enää tuota keksiä ole. "Uloskirjattu" JWT vanhenee sitten itsestään 12 tunnissa ja siten pienennetään tietoturvariskiä eikä sinun tarvitse huolehtia karanneista tokeneista koska niiden elinikä on suhteellisen lyhyt.

Jos palvelussa ei ole rahaliikennettä, henkilötietoja tai muuta arkaluonteista niin tämä on varmaan ihan kelpo ratkaisu.
 
Viimeksi muokattu:
Yksi helppo ja karvalakkimallinen JWT-toteutus olisi tehdä siten, että pidät tokenia voimassa yhden päivän eli vaikka 12 tuntia. Pistät JWT:n httpOnly keksiin, ei blacklist-tietokantaa tai refreshiä ja logout-rutiini poistaa keksin käyttäjän selaimesta. Tässä miinuksena se että käyttäjä joutuu kirjautumaan uudestaan palveluun joka 12 tunti, eli päivittäin palvelua käyttävät kirjautuvat joka päivä uudestaan.

Kun käyttäjä on manuaalisesti kirjautunut ulos niin tietty se JWT on edelleen validi itsessään ja jos joku on sen tokenin sattunut saamaan, on se validi palvelimelle. Käyttäjän pitää kirjautua uudestaan uloskirjatumisen jälkeen, koska hänen selaimessaan ei enää tuota keksiä ole. "Uloskirjattu" JWT vanhenee sitten itsestään 12 tunnissa ja siten pienennetään tietoturvariskiä eikä sinun tarvitse huolehtia karanneista tokeneista koska niiden elinikä on suhteellisen lyhyt.

Jos palvelussa ei ole rahaliikennettä, henkilötietoja tai muuta arkaluonteista niin tämä on varmaan ihan kelpo ratkaisu.

Itse menis simppelissä prokkiksessa (firebasella mutta jos ei mahdollista niin...) Express-Sessiolla ja siihen kylkeen sequelize + sqlite ja bcryptillä passun validointi...
Tää prokkis tuskin hyötyy tilattomasta jwt vs sessio mitenkään erityisesti?
 
Toi on aika klassinen tapaus miten painotella näiden välillä:
  • Toteutuksen monimutkaisuus
  • Tietoturva
  • Käyttäjäystävällisyys
  • Suorituskyky ja skaalautuvuus
Pitää miettiä ensin että mihin palvelu on tarkoitettu, paljon siellä on käyttäjiä, paljonko tarvitaan suorituskykyä, mitä käyttäjät odottavat palvelulta, mitä dataa palvelussa on ja kuinka turvallinen sen pitää olla. Kun noi on selvillä niin valitaan teknologia sen toteutukseen. JWT tosiaan on aika ison maailman juttuja.
 
Taidan nyt mennä tuolla JWT toteutuksella, jossa token kulkee httpOnly keksissä lyhyellä voimassaoloajalla.
 
Javascriptillä tehtäessä oliota jossa pitäisi tulostaa lause niistä kerätyistä tiedoista, joutuuko aina tekemään objektin (olion nimi) sekä myös metodin (funktio)?
 
Javascriptillä tehtäessä oliota jossa pitäisi tulostaa lause niistä kerätyistä tiedoista, joutuuko aina tekemään objektin (olion nimi) sekä myös metodin (funktio)?

Teet olion jolla on toString tai miksi ikinä haluatkaan sitä fn kutsua.

Olio.toString() sitten palauttaa ko olion sisällön

JavaScript:
function Person(firstName,lastName){
  this.firstName = firstName;
  this.lastName = lastName;
  this.toString = function(){
      return this.firstName+' '+this.lastName;
  }
}

const Pekka = new Person('Pekka','Puupää')

Pekka.toString() /* -> Pekka Puupää */
 
Siis periaatteessa tarviiko tuon lisäksi mitään muuta, vai onko tuossa koko setti?
Voitko vähän selventää tuota.
 
Siis periaatteessa tarviiko tuon lisäksi mitään muuta, vai onko tuossa koko setti?
Voitko vähän selventää tuota.

Siinä on luokka, joka sisältää tietoa ja tulostusfunkkarin sille tiedolle. Seuraavaksi siinä luodaan olio, joillakin tiedoilla. Tämän jälkeen tuon olion tulostusfunkkaria kutsutaan, ja se suorittaa siellä luokassa määritetyn tulostuksen.

Eli tuon esimerkin perusteella näet miten luokassa olevaa tietoa voidaan tulostaa funkkarissa. Omassa toteutuksessasi sitten tallentelet mitä tallentelet, ja tulostuksessa tulostat mitä haluat, viittaamalla esimerkin näyttämällä tavalla siihen tietoon (mahdollisesti luuppaamalla jos tarvii).
 

Uusimmat viestit

Statistiikka

Viestiketjuista
261 742
Viestejä
4 538 006
Jäsenet
74 870
Uusin jäsen
Mikemo

Hinta.fi

Back
Ylös Bottom