728x90

출처

가상 레코드 생성 예제

public class DemoReport {
	
	public static void main(String[] args) throws Exception {
		JasperReport jasperReport = JasperCompileManager.compileReport("src/ireport/report1.jrxml");
		
		// creating the data source
		JRDataSource dataSource = new JREmptyDataSource(1000); // 가상의 1000개의 레코드 생성
		
		JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null, dataSource);
		
		// view report to UI
		jasperReport.setWhenNoDataType(WhenNoDataTypeEnum.ALL_SECTIONS_NO_DETAIL);
		JasperViewer.viewReport(jasperPrint, false);
	}
}

PDF 출력 예제

public class DemoReport2 {

	public static void main(String[] args) throws Exception {
		String outfilename = "src/ireport/report1.pdf";
		JasperReport jasperReport = JasperCompileManager.compileReport("src/ireport/report1.jrxml");

		// compile report hm.put(“REPORT_TITLE”,”This is the title of the report”)
		HashMap<String, Object> hm = new HashMap<String, Object>();
		hm.put("id", "121");

		List list = new ArrayList();
		list.add("test data");
		JRBeanCollectionDataSource jrbcds = new JRBeanCollectionDataSource(list, false);

		// 리포트 목록
		// List<JasperPrint> japerPrintList = new ArrayList<JasperPrint>();

		JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, hm, jrbcds);

		// PDF 출력
		JRExporter ex = new JRPdfExporter();
		ex.setParameter(JRPdfExporterParameter.IS_COMPRESSED, true);
		ex.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, outfilename);
		// ex.setParameter(JRExporterParameter.JASPER_PRINT_LIST, japerPrintList);
		ex.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
		ex.exportReport();
	}
}

JRDataSource 확장

필드 추가

필드 이름 변경

필드 객체를 선택해서 Detail 밴드에 드래그해 놓기

필드 배치

최종 결과물

커스텀 JRDataSource

import java.util.HashMap;
import java.util.Map;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;

public class SampleDS implements JRDataSource {

	String[] fields;
	String[][] data;

	private Map<String, Integer> fieldIndex = new HashMap<String, Integer>();
	
	public SampleDS(String[] fields, String[][] data) {
		this.fields = fields;
		this.data = data;

		for (int i = 0; i < fields.length; i++)
			fieldIndex.put(fields[i], i);
	}

	int pos = -1;

	@Override
	public boolean next() throws JRException {
		for (;;) {
			pos++;
			if (pos >= data.length)
				return false;

			return true;
		}
	}

	@Override
	public Object getFieldValue(JRField jrField) throws JRException {
		Integer index = fieldIndex.get(jrField.getName());
		return data[pos][index];
	}
	
	public static JRDataSource getDataSource() {
		String[] fields = { "a", "b", "c", "d", "e" }; 
		String[][] data = {
				{ "a1", "b1", "c1", "d1", "e1" },
				{ "a2", "b2", "c2", "d2", "e2" },
				{ "a3", "b3", "c3", "d3", "e3" }
		};
		
		return new SampleDS(fields, data);
	}

}

예제소스

public class DemoReport3 {
	
	public static void main(String[] args) throws Exception {
		String outfilename = "src/ireport/report2.pdf";
		JasperReport jasperReport = JasperCompileManager.compileReport("src/ireport/report2.jrxml");
		
		// 커스텀 JRDataSource 생성
		JRDataSource dataSource = SampleDS.getDataSource();
		
		//
		JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null, dataSource);

		// PDF 출력
		JRExporter ex =new JRPdfExporter();
		ex.setParameter(JRPdfExporterParameter.IS_COMPRESSED, true);
		ex.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, outfilename);
		//ex.setParameter(JRExporterParameter.JASPER_PRINT_LIST, japerPrintList);
		ex.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
		ex.exportReport();
	}

}

실행

동적으로 이미지 출력

디자인

Image Expression

$P{image_home}+"/"+$F{image1}

ImageBean 소스

public class ImageBean {
	
	private String image1;
	
	private String image2;

	public ImageBean(String image1, String image2) {
		super();
		this.image1 = image1;
		this.image2 = image2;
	}

	public String getImage1() {
		return image1;
	}

	public void setImage1(String image1) {
		this.image1 = image1;
	}

	public String getImage2() {
		return image2;
	}

	public void setImage2(String image2) {
		this.image2 = image2;
	}

}

이미지 출력 예제 소스

public class DemoReport4 {
	
	public static void main(String[] args) throws Exception {
		String outfilename = "src/ireport/report3.pdf";
		JasperReport jasperReport = JasperCompileManager.compileReport("src/ireport/report3.jrxml");
		
		// compile report hm.put(“REPORT_TITLE”,”This is the title of the report”)
		HashMap<String, Object> hm = new HashMap<String, Object>();
		hm.put("image_home", "C:\\Users\\bluesanta\\Pictures");
		
		//
		List list = new ArrayList();
		list.add(new ImageBean("73196c49-adeb-4ebd-9bde-069791498a28.jpg", "70947765.jpg"));
		JRBeanCollectionDataSource jrbcds = new JRBeanCollectionDataSource(list, false);
		
		// 리포트 목록
		// List<JasperPrint> japerPrintList = new ArrayList<JasperPrint>();

		JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, hm, jrbcds);

		// PDF 출력
		JRExporter ex = new JRPdfExporter();
		ex.setParameter(JRPdfExporterParameter.IS_COMPRESSED, true);
		ex.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, outfilename);
		// ex.setParameter(JRExporterParameter.JASPER_PRINT_LIST, japerPrintList);
		ex.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
		ex.exportReport();
	}

}
728x90
728x90

출처

MMDevApi.pas

unit MMDevApi;

interface

uses
  Windows, ActiveX, ComObj;

const
  CLSID_MMDeviceEnumerator : TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';
  IID_IMMDeviceEnumerator : TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';
  IID_IMMDevice : TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';
  IID_IMMDeviceCollection : TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}';
  IID_IAudioEndpointVolume : TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';
  IID_IAudioMeterInformation : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';
  IID_IAudioEndpointVolumeCallback : TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';
  IID_IMMNotificationClient : TGUID = '{7991EEC9-7E89-4D85-8390-6C703CEC60C0}';

  DEVICE_STATE_ACTIVE = $00000001;
  DEVICE_STATE_UNPLUGGED = $00000002;
  DEVICE_STATE_NOTPRESENT = $00000004;
  DEVICE_STATEMASK_ALL = $00000007;

type
 PAUDIO_VOLUME_NOTIFICATION_DATA = ^AUDIO_VOLUME_NOTIFICATION_DATA;
 AUDIO_VOLUME_NOTIFICATION_DATA = packed record
  guidEventContext: TGUID;
  bMuted: BOOL;
  fMasterVolume: Single;
  nChannels: UINT;
  afChannelVolumes: array[1..1] of Single;
 end;

type
  EDataFlow = TOleEnum;

const
  eRender = $00000000;
  eCapture = $00000001;
  eAll = $00000002;
  EDataFlow_enum_count = $00000003;

type
  ERole = TOleEnum;

const
  eConsole = $00000000;
  eMultimedia = $00000001;
  eCommunications = $00000002;
  ERole_enum_count = $00000003;

type
  IAudioEndpointVolumeCallback = interface(IUnknown)
  [IID_IAudioEndpointVolumeCallback]
    function OnNotify(pNotify: PAUDIO_VOLUME_NOTIFICATION_DATA): HRESULT; stdcall;
  end;

  IAudioEndpointVolume = interface(IUnknown)
  [IID_IAudioEndpointVolume]
    function RegisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
    function UnregisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
    function GetChannelCount(out PInteger): Integer; stdcall;
    function SetMasterVolumeLevel(fLevelDB: single; pguidEventContext: PGUID): Integer; stdcall;
    function SetMasterVolumeLevelScalar(fLevelDB: single; pguidEventContext: PGUID): Integer; stdcall;
    function GetMasterVolumeLevel(out fLevelDB: single): Integer; stdcall;
    function GetMasterVolumeLevelScaler(out fLevelDB: single): Integer; stdcall;
    function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): Integer; stdcall;
    function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): Integer; stdcall;
    function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: double): Integer; stdcall;
    function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: double): Integer; stdcall;
    function SetMute(bMute: Boolean; pguidEventContext: PGUID): Integer; stdcall;
    function GetMute(out bMute: Boolean): Integer; stdcall;
    function GetVolumeStepInfo(pnStep: Integer; out pnStepCount: Integer): Integer; stdcall;
    function VolumeStepUp(pguidEventContext: PGUID): Integer; stdcall;
    function VolumeStepDown(pguidEventContext: PGUID): Integer; stdcall;
    function QueryHardwareSupport(out pdwHardwareSupportMask): Integer; stdcall;
    function GetVolumeRange(out pflVolumeMindB: double; out pflVolumeMaxdB: double; out pflVolumeIncrementdB: double): Integer; stdcall;
  end;

  IAudioMeterInformation = interface(IUnknown)
  [IID_IAudioMeterInformation]
    function GetPeakValue(out Peak: Real): HRESULT; stdcall;
  end;

  IPropertyStore = interface(IUnknown)
  end;

  IMMDevice = interface(IUnknown)
  [IID_IMMDevice]
    function Activate(const refId: TGUID; dwClsCtx: DWORD; pActivationParams: PInteger; out pEndpointVolume: IAudioEndpointVolume): HRESULT; stdCall;
    function OpenPropertyStore(stgmAccess: DWORD; out ppProperties: IPropertyStore): HRESULT; stdcall;
    function GetId(out ppstrId: PLPWSTR): HRESULT; stdcall;
    function GetState(out State: Integer): HRESULT; stdcall;
  end;

  IMMDeviceCollection = interface(IUnknown)
  [IID_IMMDeviceCollection]
    function GetCount(out pcDevices: UINT): HRESULT; stdcall;
    function Item(nDevice: UINT; out ppDevice: IMMDevice): HRESULT; stdcall;
  end;

  IMMNotificationClient = interface(IUnknown)
  [IID_IMMNotificationClient]
  end;

  IMMDeviceEnumerator = interface(IUnknown)
  [IID_IMMDeviceEnumerator]
    function EnumAudioEndpoints(dataFlow: EDataFlow; deviceState: SYSUINT; out DevCollection: IMMDeviceCollection): HRESULT; stdcall;
    function GetDefaultAudioEndpoint(EDF: SYSUINT; ER: SYSUINT; out Dev: IMMDevice): HRESULT; stdcall;
    function GetDevice(pwstrId: pointer; out Dev: IMMDevice): HRESULT; stdcall;
    function RegisterEndpointNotificationCallback(pClient: IMMNotificationClient): HRESULT; stdcall;
    function UnregisterEndpointNotificationCallback(pClient: IMMNotificationClient): HRESULT; stdcall;
  end;

implementation

end.

Demo

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  MMDevApi, ActiveX, ComObj, Vcl.ComCtrls, Vcl.StdCtrls;

type
  TEndpointVolumeCallback = class(TInterfacedObject, IAudioEndpointVolumeCallback)
    function OnNotify(pNotify: PAUDIO_VOLUME_NOTIFICATION_DATA): HRESULT; stdcall;
  end;

  TForm1 = class(TForm)
    trackVolumeLevel: TTrackBar;
    spdMute: TCheckBox;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    endpointVolume: IAudioEndpointVolume;
  public
    { Public declarations }
    procedure doMasterVolumeMute(bMute: Boolean);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.doMasterVolumeMute(bMute: Boolean);
var
  MMDeviceCollection: IMMDeviceCollection;
  MMDeviceEnumerator: IMMDeviceEnumerator;
  device :IMMDevice ;
  hr: HRESULT;
  deviceCount : UINT;
  i : integer;
begin
  hr := CoCreateInstance(CLSID_MMDeviceEnumerator, nil, CLSCTX_ALL, IID_IMMDeviceEnumerator, MMDeviceEnumerator);
  if hr <> ERROR_SUCCESS then ShowMessage(SysErrorMessage(hr));

  MMDeviceCollection := nil; // wegen dem OUT-Parameter *1
  hr := MMDeviceEnumerator.EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, MMDeviceCollection);
  if hr <> ERROR_SUCCESS then ShowMessage(SysErrorMessage(hr));

  hr := MMDeviceCollection.GetCount(deviceCount);
  if hr <> ERROR_SUCCESS then ShowMessage(SysErrorMessage(hr));

  for i:=0 to deviceCount-1 do begin
    MMDeviceCollection.Item(i, device);
    endpointVolume:=nil;
    device.Activate(IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, nil, endpointVolume);
    endpointVolume.SetMute(bMute,nil);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  doMasterVolumeMute(true);
end;

end.
728x90
728x90

출처

/config/dbHelper.js

const mariadb = require('mariadb');
var config = require('./db_config');    // ./는 현재 디렉토리를 나타냅니다

const pool = mariadb.createPool({
    host: config.host,
    port: config.port,
    user: config.user,
    password: config.password,
    database: config.database,
    connectionLimit: 5
});

function dbHelper() {
    //
    this.getConnection = function(callback) {
        pool.getConnection()
            .then(conn => {
                callback(conn);
            }).catch(err => {
            //not connected
        });
    };

    //
    this.getConnectionAsync = async function() {
        try {
            let conn = await pool.getConnection();
            // console.log("conn = " + conn); // { affectedRows: 1, insertId: 1, warningStatus: 0 }
            return conn;
        } catch (err) {
            throw err;
        }
        return null;
    };

    //
    this.sendJSON = function(response, httpCode, body) {
        var result = JSON.stringify(body);
        response.send(httpCode, result);
    };
}

module.exports = new dbHelper();

/config/passport.js

var dbHelper = require('./dbHelper');
const LocalStrategy = require('passport-local').Strategy;

module.exports = (passport) => {

    // 로그인이 성공하면, serializeUser 메서드를 이용하여 사용자 정보를 Session에 저장할 수 있다.
    passport.serializeUser((user, done) => {
        console.log('serialize');
        done(null, user);
    });

    // 인증 후, 페이지 접근시 마다 사용자 정보를 Session에서 읽어옴.
    passport.deserializeUser((user, done) => {
        console.log('deserialize');
        done(null, user);
    });

    passport.use(new LocalStrategy({
            usernameField : 'userid',
            passwordField : 'password',
            passReqToCallback : true
        },

        // 인증 요청
        function(req, userid, password, done) {
            if(!userid || !password ) { return done(null, false, req.flash('message','All fields are required.')); }
            dbHelper.getConnection(function(conn) {
                console.log('conn = ' + conn);
                conn.query("select * from member where email = ?", [userid]).then((rows) => {
                    // console.log(rows);
                    if(!rows.length) {
                        return done(null, false, req.flash('message','Invalid username or password.'));
                    }
                    var dbPassword  = rows[0].password;
                    if(!(dbPassword == password)) {
                        return done(null, false, req.flash('message','Invalid username or password.'));
                    }
                    return done(null, rows[0]);
                })
                .then((res) => {
                    console.log('res = '+res); // { affectedRows: 1, insertId: 1, warningStatus: 0 }
                    conn.end();
                })
                .catch(err => {
                    //handle error
                    console.log(err);
                    conn.end();
                    if (err) return done(req.flash('message',err));
                });
            });
        }
    ));
};

웹페이지에 값 전달 (connect-flash 모듈)

/app.js

var flash = require('connect-flash');

app.use(passport.session()); //로그인 세션 유지
app.use(flash());
728x90
728x90

출처

/config/db_config.js

module.exports = (function() {
    return {
        host: "localhost",
        port : 10312,
        user: "root",
        password: "sqldba",
        database: "simplesns"
    }
})();

/config/dbHelper.js

const mariadb = require('mariadb');
var config = require('./db_config');    // ./는 현재 디렉토리를 나타냅니다

const pool = mariadb.createPool({
    host: config.host,
    port: config.port,
    user: config.user,
    password: config.password,
    database: config.database,
    connectionLimit: 5
});

function dbHelper() {
    //
    this.getConnection = function(callback) {
        pool.getConnection()
            .then(conn => {
                callback(conn);
            }).catch(err => {
            //not connected
        });
    };

    //
    this.getConnectionAsync = async function() {
        try {
            let conn = await pool.getConnection();
            // console.log("conn = " + conn); // { affectedRows: 1, insertId: 1, warningStatus: 0 }
            return conn;
        } catch (err) {
            throw err;
        }
        return null;
    };

    //
    this.sendJSON = function(response, httpCode, body) {
        var result = JSON.stringify(body);
        response.send(httpCode, result);
    };
}

module.exports = new dbHelper();

/api/user/UserService.js

var dbHelper = require('../../config/dbHelper');

// https://github.com/jareddlc/node-datatables/blob/master/server.js
function UserService() {
    this.getUserList = function(request, response) {
        dbHelper.getConnection(function(conn) {
            conn.query('SELECT * FROM member')
                .then((results) => {
                    // console.log(results); //[ {val: 1}, meta: ... ]

                    //Output
                    var output = {};
                    var temp = [];
                    output.datas = results;
                    
                    dbHelper.sendJSON(response, 200, output);
                })
                .then((res) => {
                    console.log('res = '+res); // { affectedRows: 1, insertId: 1, warningStatus: 0 }
                    conn.end();
                })
                .catch(err => {
                    //handle error
                    console.log(err);
                    conn.end();
                })
        });
    }
}

module.exports = new UserService();
728x90
728x90

출처

/api/user/user.ctrl.js

/* api 로직 */
let users = [
    {id: 1, name: 'jinbro'},
    {id: 2, name: 'jinhyung'},
    {id: 3, name: 'park'}
];

let index = function(req, res) {
    if(!req.query.limit){
        res.json(users);
    } else {
        const limit = parseInt(req.query.limit, 10);

        if(isNaN(limit)){
            return res.status(400).end();
        }
        res.json(users.slice(0, limit));
    }
};

let read = function(req, res) {
    const id = parseInt(req.params.id, 10);

    console.log("id = " + id);

    if(isNaN(id)) {
        return res.status(400).end();
    }

    const user = users.filter((user) => {
        return user.id === id;
    })[0];

    if(!user) {
        return res.status(404).end();
    }

    res.json(user);
};

module.exports = {
    index: index,
    read: read
    //create: create,
    //update: update,
    //destroy: destroy
};

/api/user/index.js

const express = require('express');
const router = express.Router();

const controller = require('./user.ctrl');

/* user 라우팅 로직 */
router.get('/', controller.index);
router.get('/:id', controller.read);
//router.post('/', controller.create);
//router.put('/:id', controller.update);
//router.delete('/:id', controller.destroy);

module.exports = router;

/app.js

/* use router class */
const user = require('./api/user/index.js');

/* /users 요청을 모두 /user/index.js로 */
app.use('/users', user);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

실행

728x90
728x90

출처

변수

출처 : 2. 기초문법 · node.js 서버구축하기

var name; // 변수 선언
name = '홍길동'; // 변수 정의

var num2 = 3; // 변수 선언과 정의

함수

출처 : 함수 표현식 vs 함수 선언식 • Captain Pangyo

함수 선언식 - Function Declarations

// 함수 선언
function funcDeclarations() {
  return 'A function declaration';
}
funcDeclarations(); // 함수 호출

함수 표현식 - Function Expressions

// 함수 표현식 -> 함수 변수 선언
var funcExpression = function () {
    return 'A function expression';
}
funcExpression(); // 함수 호출

조건문

if < > && || ==

반복문

for, while

클래스

// User 클래스 선언
function User(_name){
    // 변수를 객체의 멤버로 사용하기 위해 this 예약어를 사용해서 정의
    this.name = _name; // 사용자 이름
    this.age = 0; // 사용자 나이

    // 사용자 이름을 반환 하는 User 클래스의 내장 함수
    this.getName = function() {
        return this.name;
    }

    this.getAge = function() {
        return this.age;
    }
}

var user1 = new User("bluexmas"); // User 객체 생성 
console.log(user1.getName()); // User 클래스의 내장 함수 호출

prototype

// User객체의 prototype을 가져와서 setAge 함수 추가
User.prototype.setAge = function(_age){
    this.age = _age;
}

user1.setAge(10);
console.log(user1.getAge()); // User 클래스의 내장 함수 호출

require - 동적 라이브러리 로딩

출처 : Node.js 기초와 모듈 (내장 모듈, npm, 사용자정의 모듈)

url 모듈을 이용해서 url 파싱하는 예제

var url = require("url");
var parsedURL = url.parse("http://www.example.com/profile?name=barry");
 
console.log(parsedURL.protocol); // "http:"
console.log(parsedURL.host); // "www.example.com"
console.log(parsedURL.query); // "name=barry"
728x90
728x90

출처

/app.js

// 모듈 추가
const passport = require('passport');
const session = require('express-session');
var bodyParser = require('body-parser');

// ... 생략 ...

/*
cookieParser
session
passport.initialize
passport.session
app.route
 */
var app = express();

// ... 생략 ...

app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// 세션 설정
app.use(session({
  secret: 'simpleSNS',
  resave: true,
  saveUninitialized: false
})); // 세션 활성화

require('./config/passport')(passport);
app.use(passport.initialize());
app.use(passport.session()); //로그인 세션 유지

app.use(bodyParser.urlencoded({extended: true}));

/public/login.html

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<form action="/login" method="post">
    <div>
        <label>UserId:</label>
        <input type="text" name="userid"/><br/>
    </div>
    <div>
        <label>Password:</label>
        <input type="password" name="password"/>
    </div>
    <div>
        <input type="submit" value="Submit"/>
    </div>
</form>
</body>
</html>

/config/passport.js

const LocalStrategy = require('passport-local').Strategy;

module.exports = (passport) => {

    // 로그인이 성공하면, serializeUser 메서드를 이용하여 사용자 정보를 Session에 저장할 수 있다.
    passport.serializeUser((user, done) => {
        console.log('serialize');
        done(null, user);
    });

    // 인증 후, 페이지 접근시 마다 사용자 정보를 Session에서 읽어옴.
    passport.deserializeUser((user, done) => {
        console.log('deserialize');
        done(null, user);
    });

    passport.use(new LocalStrategy({
            usernameField : 'userid',
            passwordField : 'password',
            passReqToCallback : true
        },
        
        // 인증 요청
        function(req, userid, password, done) {
            if(userid=='test' && password=='1111') {
                var user = {
                    'userid':'hello',
                    'email':'hello@world.com'
                };
                return done(null, user);
            }else{
                return done(null, false);
            }
        }
    ));
};

/routes/index.js

var express = require('express');
var router = express.Router();
const passport = require('passport');

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

// 로그인
router.post('/login', passport.authenticate('local', {failureRedirect: '/login.html'}), (req, res) => {
  res.redirect('/login_suc.html');
});

/*
router.post('/login', passport.authenticate('local', {
  successRedirect: '/login_suc.html',
  failureRedirect: '/login.html'
}));
*/

// 로그아웃
router.get('/logout', (req, res) => {
  req.logout();
  res.redirect('/');
});

module.exports = router;

Facebook 로그인 적용

/config/passport.js 내용 추가

const FacebookStrategy = require('passport-facebook').Strategy;

module.exports = (passport) => {

// ... 생략 ...

    passport.use(new FacebookStrategy({
            clientID: "",
            clientSecret: "",
            profileFields: ['id', 'displayName', 'photos'],
            callbackURL: 'http://localhost:3000/markdown/auth/facebook/callback'
        },

        function (accessToken, refreshToken, profile, done) {
            const socialId = profile.id;
            const nickname = profile.displayName;
            const profileImageUrl = profile.photos[0].value;

            onLoginSuccess('Facebook', socialId, nickname, profileImageUrl, done);
        }
    ));

/routes/index.js 내용 추가

// ... 생략 ...

// 로그아웃
router.get('/logout', (req, res) => {
  req.logout();
  res.redirect('/');
});

// 페이스북 로그인 시작
router.get('/facebook', passport.authenticate('facebook'));

// 페이스북 로그인 결과 콜백
router.get('/facebook/callback', passport.authenticate('facebook', {
    failureRedirect: '/markdown/auth/login'
}), (req, res) => {
    loginSuccessHandler(req, res);
});

module.exports = router;
728x90
728x90

출처

프로젝트 생성

express 프로젝트 생성

express 프로젝트 실행

실행결과

728x90

+ Recent posts